From 3dde6326c8ba77b2200fa5ad90a847d871b78c2c Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Mon, 29 Jul 2019 18:39:59 +0200 Subject: [PATCH] Update to 2.11.0 --- openvidu-electron/package-lock.json | 316 +- openvidu-electron/package.json | 2 +- openvidu-electron/src/index.html | 2 +- .../src/openvidu-browser-2.10.0.js | 8566 --------- .../src/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-filters/web/index.html | 2 +- .../web/openvidu-browser-2.10.0.js | 8566 --------- .../web/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-getaroom/docker/Dockerfile | 2 +- openvidu-getaroom/web/index.html | 2 +- .../web/openvidu-browser-2.10.0.js | 8566 --------- .../web/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-hello-world/web/index.html | 2 +- .../web/openvidu-browser-2.10.0.js | 8566 --------- .../web/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-insecure-angular/package-lock.json | 973 +- openvidu-insecure-angular/package.json | 4 +- openvidu-insecure-js/docker/Dockerfile | 2 +- openvidu-insecure-js/web/index.html | 2 +- .../web/openvidu-browser-2.10.0.js | 8566 --------- .../web/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-insecure-react/package-lock.json | 1644 +- openvidu-insecure-react/package.json | 4 +- openvidu-internet-explorer/web/index.html | 2 +- .../web/openvidu-browser-2.10.0.js | 8566 --------- .../web/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-ionic/package-lock.json | 15147 +++++++++------- openvidu-ionic/package.json | 6 +- openvidu-js-java/docker/Dockerfile | 2 +- openvidu-js-java/pom.xml | 4 +- .../src/main/resources/static/index.html | 2 +- .../static/openvidu-browser-2.10.0.js | 8566 --------- .../static/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-js-node/package-lock.json | 8 +- openvidu-js-node/package.json | 4 +- openvidu-js-node/public/index.html | 2 +- .../public/openvidu-browser-2.10.0.js | 8566 --------- .../public/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-library-angular/package-lock.json | 1087 +- openvidu-library-angular/package.json | 4 +- openvidu-library-react/package-lock.json | 1686 +- openvidu-library-react/package.json | 4 +- openvidu-mvc-java/pom.xml | 4 +- .../static/openvidu-browser-2.10.0.js | 8566 --------- .../static/openvidu-browser-2.11.0.js | 8661 +++++++++ .../src/main/resources/templates/session.html | 2 +- openvidu-mvc-node/package-lock.json | 8 +- openvidu-mvc-node/package.json | 4 +- .../public/openvidu-browser-2.10.0.js | 8566 --------- .../public/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-mvc-node/views/session.ejs | 2 +- openvidu-react-native/package-lock.json | 1153 +- openvidu-react-native/package.json | 4 +- openvidu-recording-java/pom.xml | 4 +- .../src/main/resources/static/index.html | 2 +- .../static/openvidu-browser-2.10.0.js | 8566 --------- .../static/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-recording-node/package-lock.json | 8 +- openvidu-recording-node/package.json | 4 +- openvidu-recording-node/public/index.html | 2 +- .../public/openvidu-browser-2.10.0.js | 8566 --------- .../public/openvidu-browser-2.11.0.js | 8661 +++++++++ openvidu-webcomponent/web/index.html | 4 +- .../web/openvidu-webcomponent-2.10.0.css | 1 - .../web/openvidu-webcomponent-2.10.0.js | 4 - .../web/openvidu-webcomponent-2.11.0.css | 1 + .../web/openvidu-webcomponent-2.11.0.js | 4 + update-tutorials-full.sh | 4 +- 68 files changed, 115770 insertions(+), 113084 deletions(-) delete mode 100644 openvidu-electron/src/openvidu-browser-2.10.0.js create mode 100644 openvidu-electron/src/openvidu-browser-2.11.0.js delete mode 100644 openvidu-filters/web/openvidu-browser-2.10.0.js create mode 100644 openvidu-filters/web/openvidu-browser-2.11.0.js delete mode 100644 openvidu-getaroom/web/openvidu-browser-2.10.0.js create mode 100644 openvidu-getaroom/web/openvidu-browser-2.11.0.js delete mode 100644 openvidu-hello-world/web/openvidu-browser-2.10.0.js create mode 100644 openvidu-hello-world/web/openvidu-browser-2.11.0.js delete mode 100644 openvidu-insecure-js/web/openvidu-browser-2.10.0.js create mode 100644 openvidu-insecure-js/web/openvidu-browser-2.11.0.js delete mode 100644 openvidu-internet-explorer/web/openvidu-browser-2.10.0.js create mode 100644 openvidu-internet-explorer/web/openvidu-browser-2.11.0.js delete mode 100644 openvidu-js-java/src/main/resources/static/openvidu-browser-2.10.0.js create mode 100644 openvidu-js-java/src/main/resources/static/openvidu-browser-2.11.0.js delete mode 100644 openvidu-js-node/public/openvidu-browser-2.10.0.js create mode 100644 openvidu-js-node/public/openvidu-browser-2.11.0.js delete mode 100644 openvidu-mvc-java/src/main/resources/static/openvidu-browser-2.10.0.js create mode 100644 openvidu-mvc-java/src/main/resources/static/openvidu-browser-2.11.0.js delete mode 100644 openvidu-mvc-node/public/openvidu-browser-2.10.0.js create mode 100644 openvidu-mvc-node/public/openvidu-browser-2.11.0.js delete mode 100644 openvidu-recording-java/src/main/resources/static/openvidu-browser-2.10.0.js create mode 100644 openvidu-recording-java/src/main/resources/static/openvidu-browser-2.11.0.js delete mode 100644 openvidu-recording-node/public/openvidu-browser-2.10.0.js create mode 100644 openvidu-recording-node/public/openvidu-browser-2.11.0.js delete mode 100644 openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.css delete mode 100644 openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.js create mode 100644 openvidu-webcomponent/web/openvidu-webcomponent-2.11.0.css create mode 100644 openvidu-webcomponent/web/openvidu-webcomponent-2.11.0.js diff --git a/openvidu-electron/package-lock.json b/openvidu-electron/package-lock.json index 2e9c403e6..a9f508dde 100644 --- a/openvidu-electron/package-lock.json +++ b/openvidu-electron/package-lock.json @@ -1,13 +1,13 @@ { "name": "openvidu-electron", - "version": "1.0.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/runtime": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", - "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", "dev": true, "optional": true, "requires": { @@ -37,9 +37,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -70,9 +70,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -127,9 +127,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -187,9 +187,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -331,9 +331,9 @@ } }, "@types/electron-packager": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@types/electron-packager/-/electron-packager-13.0.0.tgz", - "integrity": "sha512-Q0e/ja/TfSSPM5rV9RxaPz8yew7dWSSufFsziw08hCZYQuafXkbhxs83UvQ/Hte3+c3U+ogLQKXFasGn1umn5A==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@types/electron-packager/-/electron-packager-13.0.1.tgz", + "integrity": "sha512-K9CCdarh7JdWvIIWM+xCWoROYXgcRFmX3OgjgwaFIFOb87bMTvtQVLyVi8LO0NroURadaae5L1AaK1BxKhytoA==", "dev": true, "requires": { "@types/node": "*" @@ -366,9 +366,9 @@ "optional": true }, "@types/node": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.4.tgz", - "integrity": "sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw==", + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", "dev": true }, "abbrev": { @@ -378,9 +378,9 @@ "dev": true }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -600,9 +600,9 @@ "dev": true }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "chromium-pickle-js": { @@ -621,9 +621,9 @@ } }, "cli-spinners": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.1.0.tgz", - "integrity": "sha512-8B00fJOEh1HPrx4fo5eW16XmE1PcL1tGpGrxy63CXGP9nHdPBN63X75hA1zhvQuhVztJWLqV58Roj2qlNM7cAA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", + "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", "dev": true }, "cli-width": { @@ -868,9 +868,9 @@ }, "dependencies": { "@types/node": { - "version": "10.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz", - "integrity": "sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==", + "version": "10.14.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.13.tgz", + "integrity": "sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ==", "dev": true } } @@ -919,9 +919,9 @@ "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "semver": { @@ -962,9 +962,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true } @@ -998,9 +998,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true } @@ -1033,9 +1033,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true } @@ -1061,17 +1061,17 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "electron-osx-sign": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", - "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.12.tgz", + "integrity": "sha512-L/+VcwO76EtP+E4Gh/HJH0exaKeYLPZlNNBFdl+Vw3il9jRBRjInpqtegLAu8t/cGGJn+tZ47Uc6mymQYNpJ6g==", "dev": true, "requires": { "bluebird": "^3.5.0", @@ -1125,9 +1125,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "semver": { @@ -1165,9 +1165,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -1207,9 +1207,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true } @@ -1303,9 +1303,9 @@ "dev": true }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -1382,39 +1382,28 @@ } }, "flora-colossus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.0.tgz", - "integrity": "sha1-VHKcNh7ezuAU3UQWeeGjfB13OkU=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.1.tgz", + "integrity": "sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA==", "dev": true, "requires": { - "debug": "^3.1.0", - "fs-extra": "^4.0.0" + "debug": "^4.1.1", + "fs-extra": "^7.0.0" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -1494,9 +1483,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -1751,9 +1740,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", "dev": true }, "har-schema": { @@ -1839,9 +1828,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ini": { @@ -1851,9 +1840,9 @@ "dev": true }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -1862,7 +1851,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -1906,12 +1895,6 @@ } } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2044,15 +2027,6 @@ "verror": "1.10.0" } }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -2085,9 +2059,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash._reinterpolate": { @@ -2109,28 +2083,28 @@ "dev": true }, "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0", + "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0" + "lodash._reinterpolate": "^3.0.0" } }, "log-symbols": { @@ -2312,9 +2286,9 @@ "dev": true }, "node-abi": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.8.0.tgz", - "integrity": "sha512-1/aa2clS0pue0HjckL62CsbhWWU35HARvBDXcJtYKbYR7LnIutmpxmXbuDMV9kEviD2lP/wACOgWmmwljghHyQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.9.0.tgz", + "integrity": "sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA==", "dev": true, "requires": { "semver": "^5.4.1" @@ -2497,9 +2471,9 @@ } }, "open": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.3.0.tgz", - "integrity": "sha512-6AHdrJxPvAXIowO/aIaeHZ8CeMdDf7qCyRNq8NwJpinmCdXhz+NZR7ie1Too94lpciCDsG+qHGO9Mt0svA4OqA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -2536,17 +2510,6 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -2742,9 +2705,9 @@ } }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "progress-stream": { @@ -2783,9 +2746,9 @@ "dev": true }, "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", "dev": true }, "pump": { @@ -2904,9 +2867,9 @@ } }, "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", "dev": true, "optional": true }, @@ -3037,18 +3000,18 @@ "dev": true }, "sanitize-filename": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", - "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.2.tgz", + "integrity": "sha512-cmTzND7RMxUB+f7gI+4+KAVHWEg0lfXvQJdko+FXDP5bNbGIdx4KMP5pX6lv5jfT9jSf6OBbjyxjFtZQwYA/ig==", "dev": true, "requires": { "truncate-utf8-bytes": "^1.0.0" } }, "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "set-blocking": { @@ -3141,9 +3104,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "speedometer": { @@ -3410,9 +3373,9 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, "tunnel-agent": { @@ -3452,9 +3415,9 @@ } }, "username": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/username/-/username-5.0.0.tgz", - "integrity": "sha512-iPfqmcRP2FMDeTFumQVCFKwi0L5npM8W/skqusA5okl8YSwAZi0mTNx04zjM14Kx66LG9IsMG4kIjsQvgz4rOQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", + "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", "dev": true, "requires": { "execa": "^1.0.0", @@ -3610,22 +3573,21 @@ "dev": true }, "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" + "yargs-parser": "^13.1.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -3648,9 +3610,9 @@ } }, "yargs-parser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.0.tgz", - "integrity": "sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/openvidu-electron/package.json b/openvidu-electron/package.json index db080d80d..f007b4111 100644 --- a/openvidu-electron/package.json +++ b/openvidu-electron/package.json @@ -1,7 +1,7 @@ { "name": "openvidu-electron", "productName": "openvidu-electron", - "version": "1.0.0", + "version": "2.11.0", "description": "OpenVidu Electron Tutorial", "main": "src/main.js", "scripts": { diff --git a/openvidu-electron/src/index.html b/openvidu-electron/src/index.html index 518f2d63c..e40d5f41f 100644 --- a/openvidu-electron/src/index.html +++ b/openvidu-electron/src/index.html @@ -6,7 +6,7 @@ OpenVidu Electron - + diff --git a/openvidu-electron/src/openvidu-browser-2.10.0.js b/openvidu-electron/src/openvidu-browser-2.10.0.js deleted file mode 100644 index 3999ea1fb..000000000 --- a/openvidu-electron/src/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcuaW5kZXhPZihwcmVmaXgpICsgcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgKDxhbnk+bWVkaWFDb25zdHJhaW50c1sndmlkZW8nXSkgPSB7XG4gICAgICAgICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2VJZDogZWxlY3Ryb25TY3JlZW5JZFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcblxuICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gJiYgIShwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSAmJiAhbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10pIHtcblxuICAgICAgICAgICAgICAgICAgLy8gQ3VzdG9tIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lIChhbmQgT3BlcmEpIGFuZCBubyBzdXBwb3J0IGZvciBNZWRpYURldmljZXMuZ2V0RGlzcGxheU1lZGlhKClcblxuICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZy5nZXRTY3JlZW5Db25zdHJhaW50cygoZXJyb3IsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yIHx8ICEhc2NyZWVuQ29uc3RyYWludHMubWFuZGF0b3J5ICYmIHNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZSA9PT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgZXJyb3IgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCwgJ1lvdSBtdXN0IGFsbG93IGFjY2VzcyB0byBvbmUgd2luZG93IG9mIHlvdXIgZGVza3RvcCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25JZCA9IHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uIS5zcGxpdCgnLycpLnBvcCgpISEudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uSWQsIChzdGF0dXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ2luc3RhbGxlZC1kaXNhYmxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdub3QtaW5zdGFsbGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVELCAoPHN0cmluZz50aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHM7XG4gICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0RGlzcGxheU1lZGlhIHN1cHBvcnQgKENocm9tZSA+PSA3MiwgRmlyZWZveCA+PSA1MilcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERlZmF1bHQgc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGZvciBDaHJvbWUvT3BlcmEsIG9yIGlzIEZpcmVmb3ggPCA2NlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJlZm94U3RyaW5nID0gcGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSA/IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZ0F1dG8uZ2V0U2NyZWVuSWQoZmlyZWZveFN0cmluZywgKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uVXJsID0gISF0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA/IHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9jaHJvbWUuZ29vZ2xlLmNvbS93ZWJzdG9yZS9kZXRhaWwvb3BlbnZpZHUtc2NyZWVuc2hhcmluZy9sZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVELCBleHRlbnNpb25VcmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCwgJ1lvdSBtdXN0IGVuYWJsZSB0aGUgc2NyZWVuIGV4dGVuc2lvbicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgPT09ICdwZXJtaXNzaW9uLWRlbmllZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW8gPSBzY3JlZW5Db25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID0gJ3NjcmVlbic7XG5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc3RyaW5nLWxpdGVyYWxcbiAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW9bJ2RldmljZUlkJ10gPSB7IGV4YWN0OiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIH07XG4gICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHN0YXJ0V3Mob25Db25uZWN0U3VjY2VzOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgaGVhcnRiZWF0OiA1MDAwLFxuICAgICAgc2VuZENsb3NlTWVzc2FnZTogZmFsc2UsXG4gICAgICB3czoge1xuICAgICAgICB1cmk6IHRoaXMud3NVcmksXG4gICAgICAgIHVzZVNvY2tKUzogZmFsc2UsXG4gICAgICAgIG9uY29ubmVjdGVkOiBvbkNvbm5lY3RTdWNjZXMsXG4gICAgICAgIG9uZGlzY29ubmVjdDogdGhpcy5kaXNjb25uZWN0Q2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgb25yZWNvbm5lY3Rpbmc6IHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgb25yZWNvbm5lY3RlZDogdGhpcy5yZWNvbm5lY3RlZENhbGxiYWNrLmJpbmQodGhpcylcbiAgICAgIH0sXG4gICAgICBycGM6IHtcbiAgICAgICAgcmVxdWVzdFRpbWVvdXQ6IDEwMDAwLFxuICAgICAgICBwYXJ0aWNpcGFudEpvaW5lZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRKb2luZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBwYXJ0aWNpcGFudFB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRQdWJsaXNoZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBwYXJ0aWNpcGFudFVucHVibGlzaGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudFVucHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRMZWZ0OiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBwYXJ0aWNpcGFudEV2aWN0ZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50RXZpY3RlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHJlY29yZGluZ1N0YXJ0ZWQ6IHRoaXMuc2Vzc2lvbi5vblJlY29yZGluZ1N0YXJ0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdG9wcGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdG9wcGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc2VuZE1lc3NhZ2U6IHRoaXMuc2Vzc2lvbi5vbk5ld01lc3NhZ2UuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vblN0cmVhbVByb3BlcnR5Q2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGZpbHRlckV2ZW50RGlzcGF0Y2hlZDogdGhpcy5zZXNzaW9uLm9uRmlsdGVyRXZlbnREaXNwYXRjaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgaWNlQ2FuZGlkYXRlOiB0aGlzLnNlc3Npb24ucmVjdkljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIG1lZGlhRXJyb3I6IHRoaXMuc2Vzc2lvbi5vbk1lZGlhRXJyb3IuYmluZCh0aGlzLnNlc3Npb24pXG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQgPSBuZXcgUnBjQnVpbGRlci5jbGllbnRzLkpzb25ScGNDbGllbnQoY29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBjbG9zZVdzKCk6IHZvaWQge1xuICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAyLCBcIkNvbm5lY3Rpb24gY2xvc2VkIGJ5IGNsaWVudFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZW5kUmVxdWVzdChtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBhbnksIGNhbGxiYWNrPyk6IHZvaWQge1xuICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIGNhbGxiYWNrID0gcGFyYW1zO1xuICAgICAgcGFyYW1zID0ge307XG4gICAgfVxuICAgIGNvbnNvbGUuZGVidWcoJ1NlbmRpbmcgcmVxdWVzdDoge21ldGhvZDpcIicgKyBtZXRob2QgKyAnXCIsIHBhcmFtczogJyArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyAnfScpO1xuICAgIHRoaXMuanNvblJwY0NsaWVudC5zZW5kKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0V3NVcmkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy53c1VyaTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZXRTZWNyZXQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zZWNyZXQ7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0UmVjb3JkZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVjb3JkZXI7XG4gIH1cblxuXG4gIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gIHByaXZhdGUgZGlzY29ubmVjdENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCcpO1xuICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbignbmV0d29ya0Rpc2Nvbm5lY3QnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlY29ubmVjdGluZ0NhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCAocmVjb25uZWN0aW5nKScpO1xuICAgIGlmICghdGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlY29ubmVjdGVkQ2FsbGJhY2soKTogdm9pZCB7XG4gICAgY29uc29sZS53YXJuKCdXZWJzb2NrZXQgcmVjb25uZWN0ZWQnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnY29ubmVjdCcsIHsgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbkxvc3RDb25uZWN0aW9uKFwibmV0d29ya0Rpc2Nvbm5lY3RcIik7XG4gICAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDEsIFwiUmVjb25uZWN0aW9uIGZhdWx0XCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5yZXNldFBpbmcoKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25SZWNvdmVyZWRDb25uZWN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNSb29tQXZhaWxhYmxlKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnNlc3Npb24gIT09IHVuZGVmaW5lZCAmJiB0aGlzLnNlc3Npb24gaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIGluc3RhbmNlIG5vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbUV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9FbGVtZW50RXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9WaWRlb0VsZW1lbnRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogUGFja3MgbG9jYWwgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGNhbiBwdWJsaXNoIGl0IHRvIGEgc2Vzc2lvbi4gSW5pdGlhbGl6ZWQgd2l0aCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlciBleHRlbmRzIFN0cmVhbU1hbmFnZXIge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgUHVibGlzaGVyIGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3RcbiAgICAgKi9cbiAgICBhY2Nlc3NBbGxvd2VkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHlvdSBoYXZlIGNhbGxlZCBbW1B1Ymxpc2hlci5zdWJzY3JpYmVUb1JlbW90ZV1dIHdpdGggdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAgKCpmYWxzZSogYnkgZGVmYXVsdClcbiAgICAgKi9cbiAgICBpc1N1YnNjcmliZWRUb1JlbW90ZSA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIHRvIHdoaWNoIHRoZSBQdWJsaXNoZXIgYmVsb25nc1xuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247IC8vIEluaXRpYWxpemVkIGJ5IFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpXG5cbiAgICBwcml2YXRlIGFjY2Vzc0RlbmllZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcbiAgICBwcml2YXRlIHBlcm1pc3Npb25EaWFsb2dUaW1lb3V0OiBOb2RlSlMuVGltZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3BlbnZpZHU6IE9wZW5WaWR1O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB2aWRlb1JlZmVyZW5jZTogSFRNTFZpZGVvRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2NyZWVuU2hhcmVSZXNpemVJbnRlcnZhbDogTm9kZUpTLlRpbWVyO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBJRUFkYXB0ZXI6IGFueTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnRWw6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBvcGVudmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgc3VwZXIobmV3IFN0cmVhbSgoISFvcGVudmlkdS5zZXNzaW9uKSA/IG9wZW52aWR1LnNlc3Npb24gOiBuZXcgU2Vzc2lvbihvcGVudmlkdSksIHsgcHVibGlzaGVyUHJvcGVydGllczogcHJvcGVydGllcywgbWVkaWFDb25zdHJhaW50czoge30gfSksIHRhcmdFbCk7XG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcblxuICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignbG9jYWwtc3RyZWFtLWRlc3Ryb3llZCcsIChyZWFzb246IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIHRoaXMuc3RyZWFtLCByZWFzb24pO1xuICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2ggb3IgdW5wdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqID4gX09ubHkgaWYgYFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpYCBoYXMgYmVlbiBjYWxsZWQgZm9yIHRoaXMgUHVibGlzaGVyX1xuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGV2ZW50IHdpdGggYGNoYW5nZWRQcm9wZXJ0eWAgc2V0IHRvIGBcImF1ZGlvQWN0aXZlXCJgIGFuZCBgcmVhc29uYCBzZXQgdG8gYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSByZXNwZWN0aXZlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCByZWNlaXZpbmcgdGhpcyBQdWJsaXNoZXIncyBzdHJlYW0gd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHB1Ymxpc2ggdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnB1Ymxpc2ggaXRcbiAgICAgKi9cbiAgICBwdWJsaXNoQXVkaW8odmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24gJiYgISF0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAnYXVkaW9BY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAncHVibGlzaEF1ZGlvJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2F1ZGlvQWN0aXZlJywgdmFsdWUsICF2YWx1ZSwgJ3B1Ymxpc2hBdWRpbycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlID0gdmFsdWU7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oXCInUHVibGlzaGVyJyBoYXMgXCIgKyAodmFsdWUgPyAncHVibGlzaGVkJyA6ICd1bnB1Ymxpc2hlZCcpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2ggb3IgdW5wdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqID4gX09ubHkgaWYgYFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpYCBoYXMgYmVlbiBjYWxsZWQgZm9yIHRoaXMgUHVibGlzaGVyX1xuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGV2ZW50IHdpdGggYGNoYW5nZWRQcm9wZXJ0eWAgc2V0IHRvIGBcInZpZGVvQWN0aXZlXCJgIGFuZCBgcmVhc29uYCBzZXQgdG8gYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSByZXNwZWN0aXZlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCByZWNlaXZpbmcgdGhpcyBQdWJsaXNoZXIncyBzdHJlYW0gd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHB1Ymxpc2ggdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnB1Ymxpc2ggaXRcbiAgICAgKi9cbiAgICBwdWJsaXNoVmlkZW8odmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24gJiYgISF0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9BY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAncHVibGlzaFZpZGVvJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvQWN0aXZlJywgdmFsdWUsICF2YWx1ZSwgJ3B1Ymxpc2hWaWRlbycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlID0gdmFsdWU7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oXCInUHVibGlzaGVyJyBoYXMgXCIgKyAodmFsdWUgPyAncHVibGlzaGVkJyA6ICd1bnB1Ymxpc2hlZCcpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIENhbGwgdGhpcyBtZXRob2QgYmVmb3JlIFtbU2Vzc2lvbi5wdWJsaXNoXV0gaWYgeW91IHByZWZlciB0byBzdWJzY3JpYmUgdG8geW91ciBQdWJsaXNoZXIncyByZW1vdGUgc3RyZWFtIGluc3RlYWQgb2YgdXNpbmcgdGhlIGxvY2FsIHN0cmVhbSwgYXMgYW55IG90aGVyIHVzZXIgd291bGQgZG8uXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9SZW1vdGUodmFsdWU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlICE9PSB1bmRlZmluZWQpID8gdmFsdWUgOiB0cnVlO1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlZFRvUmVtb3RlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc3RyZWFtLnN1YnNjcmliZVRvTXlSZW1vdGUodmFsdWUpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBzdXBlci5vbih0eXBlLCBoYW5kbGVyKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1DcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogUHVibGlzaGVyIHtcbiAgICAgICAgc3VwZXIub25jZSh0eXBlLCBoYW5kbGVyKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1DcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uY2UoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHRoaXMuc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3JlbW90ZVZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSAmJiB0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzQWxsb3dlZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFjY2Vzc0FsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0RlbmllZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFjY2Vzc0RlbmllZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBsZXQgY29uc3RyYWludHNBdXg6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVGb3JEaWFsb2dFdmVudCA9IDEyNTA7XG4gICAgICAgICAgICBsZXQgc3RhcnRUaW1lO1xuXG4gICAgICAgICAgICBjb25zdCBlcnJvckNhbGxiYWNrID0gKG9wZW5WaWR1RXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0RlbmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NBbGxvd2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5yZW1vdmVUcmFjayhtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5yZW1vdmVUcmFjayhtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvIGFuZCBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlb1xuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlICE9PSBudWxsKSA/IHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSBudWxsKSA/IHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG5cbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRNZWRpYVN0cmVhbShtZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLmZpcnN0VmlkZW9FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlVmlkZW9FbGVtZW50KHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudGFyZ2V0RWxlbWVudCwgPFZpZGVvSW5zZXJ0TW9kZT50aGlzLnByb3BlcnRpZXMuaW5zZXJ0TW9kZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbTtcblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgc3Vic2NyaWJlZCB0byBvdXIgcmVtb3RlIHdlIGRvbid0IHN0aWxsIHNldCB0aGUgTWVkaWFTdHJlYW0gb2JqZWN0IGluIHRoZSB2aWRlbyBlbGVtZW50cyB0b1xuICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBlYXJseSAnc3RyZWFtUGxheWluZycgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10gfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMgb3IgU2FmYXJpLiBMaW1pdGF0aW9uOiBjYW5ub3Qgc2V0IHZpZGVvRGltZW5zaW9ucyBkaXJlY3RseSwgYXMgdGhlIHZpZGVvUmVmZXJlbmNlIGlzIG5vdCBsb2FkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBub3QgYWRkZWQgdG8gRE9NLiBNdXN0IGFkZCBpdCB0byBET00gYW5kIHdhaXQgZm9yIHZpZGVvV2lkdGggYW5kIHZpZGVvSGVpZ2h0IHByb3BlcnRpZXMgdG8gYmUgZGVmaW5lZFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2aWRlb0RpbWVuc2lvbnNTZXQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLnZpZGVvUmVmZXJlbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UuYWRkRXZlbnRMaXN0ZW5lcignbG9hZGVkbWV0YWRhdGEnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uc1NldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uc1NldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2l0aCBubyBzY3JlZW4gc2hhcmUsIHZpZGVvIGRpbWVuc2lvbiBjYW4gYmUgc2V0IGRpcmVjdGx5IGZyb20gTWVkaWFTdHJlYW0gKGdldFNldHRpbmdzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWVudGF0aW9uIG11c3QgYmUgY2hlY2tlZCBmb3IgbW9iaWxlIGRldmljZXMgKHdpZHRoIGFuZCBoZWlnaHQgYXJlIHJldmVyc2VkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ2lPUycgfHwgcGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdBbmRyb2lkJykgJiYgKHdpbmRvdy5pbm5lckhlaWdodCA+IHdpbmRvdy5pbm5lcldpZHRoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNb2JpbGUgcG9ydHJhaXQgbW9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogaGVpZ2h0IHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHdpZHRoIHx8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2l0aCBzY3JlZW4gc2hhcmUsIHZpZGVvIGRpbWVuc2lvbiBtdXN0IGJlIGdvdCBmcm9tIGEgdmlkZW8gZWxlbWVudCAob25sb2FkZWRtZXRhZGF0YSBldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UuYWRkRXZlbnRMaXN0ZW5lcignbG9hZGVkbWV0YWRhdGEnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NyZWVuU2hhcmVSZXNpemVJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCA6IGZpcmVmb3hTZXR0aW5ncy53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gKHBsYXRmb3JtLm5hbWUgPT09ICdDaHJvbWUnIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdPcGVyYScpID8gdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCA6IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmV3V2lkdGggIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCAhPT0gdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0geyB3aWR0aDogdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLndpZHRoLCBoZWlnaHQ6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeSh0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb246ICdzY3JlZW5SZXNpemVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCBvbGRWYWx1ZSwgJ3NjcmVlblJlc2l6ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TWVkaWFTdWNjZXNzID0gKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSAmJiB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gZ2V0dGluZyBkZXNrdG9wIGFzIHVzZXIgbWVkaWEgYXVkaW8gY29uc3RyYWludCBtdXN0IGJlIGZhbHNlLiBOb3cgd2UgY2FuIGFzayBmb3IgaXQgaWYgcmVxdWlyZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXguYXVkaW8gPSBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC52aWRlbyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oYXVkaW9Pbmx5U3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhhdWRpb09ubHlTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBPdmVyQ29uc3RyYWluZWRFcnJvciBoYXMgYXMgbmFtZSBwcm9wZXJ0eSAnRXJyb3InIGluc3RlYWQgb2YgJ092ZXJDb25zdHJhaW5lZEVycm9yJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5uYW1lID0gZXJyb3IuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZXJyb3IubmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGZvdW5kZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90YWxsb3dlZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29uc3RyYWludC50b0xvd2VyQ2FzZSgpID09PSAnZGV2aWNlaWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TWVkaWFFcnJvciA9IGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW86IGNvbnN0cmFpbnRzLnZpZGVvXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90YWxsb3dlZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEIDogT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ292ZXJjb25zdHJhaW5lZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW86IGNvbnN0cmFpbnRzLnZpZGVvXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICsgKDxDb25zdHJhaW5ET01TdHJpbmdQYXJhbWV0ZXJzPig8TWVkaWFUcmFja0NvbnN0cmFpbnRzPmNvbnN0cmFpbnRzLmF1ZGlvKS5kZXZpY2VJZCEhKS5leGFjdCArIFwiJyBub3QgZm91bmRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICsgKDxDb25zdHJhaW5ET01TdHJpbmdQYXJhbWV0ZXJzPig8TWVkaWFUcmFja0NvbnN0cmFpbnRzPmNvbnN0cmFpbnRzLnZpZGVvKS5kZXZpY2VJZCEhKS5leGFjdCArIFwiJyBub3QgZm91bmRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJWaWRlbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhYm9ydGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90cmVhZGFibGVlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUxSRUFEWV9JTl9VU0U7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgbmV3IGNvbnN0cmFpbnRzIG5lZWQgdG8gYmUgZ2VuZXJhdGVkLiBObyBjb25zdHJhaW50cyBuZWVkZWQgaWZcbiAgICAgICAgICAgIC8vIC0gdmlkZW8gdHJhY2sgaXMgZ2l2ZW4gYW5kIG5vIGF1ZGlvXG4gICAgICAgICAgICAvLyAtIGF1ZGlvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyB2aWRlb1xuICAgICAgICAgICAgLy8gLSBib3RoIHZpZGVvIGFuZCBhdWRpbyB0cmFja3MgYXJlIGdpdmVuXG4gICAgICAgICAgICBpZiAoKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrICYmICF0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpXG4gICAgICAgICAgICAgICAgfHwgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrICYmICF0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpXG4gICAgICAgICAgICAgICAgfHwgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBNZWRpYVN0cmVhbVRyYWNrcyBhcmUgaGFuZGxlZCB3aXRoaW4gY2FsbGJhY2sgLSBqdXN0IGNhbGwgY2FsbGJhY2sgd2l0aCBuZXcgTWVkaWFTdHJlYW0oKSBhbmQgbGV0IGl0IGhhbmRsZSB0aGUgc291cmNlc1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgLy8gUmV0dXJuIGFzIHdlIGRvIG5vdCBuZWVkIHRvIHByb2Nlc3MgZnVydGhlclxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHModGhpcy5wcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIC50aGVuKG15Q29uc3RyYWludHMgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzID0gbXlDb25zdHJhaW50cztcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiBjb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlclByb3BlcnRpZXM6IHRoaXMucHJvcGVydGllc1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNldE91dGJvdW5kU3RyZWFtT3B0aW9ucyhvdXRib3VuZFN0cmVhbU9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRWaWRlbygpIHx8IHRoaXMuc3RyZWFtLmlzU2VuZEF1ZGlvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQgPSAoKGNvbnN0cmFpbnRzLmF1ZGlvID09PSB1bmRlZmluZWQpID8gdHJ1ZSA6IGNvbnN0cmFpbnRzLmF1ZGlvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgPyBmYWxzZSA6IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC52aWRlbyA9IGNvbnN0cmFpbnRzLnZpZGVvO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHRpbWVGb3JEaWFsb2dFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSAmJiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSAmJiBwbGF0Zm9ybS5uYW1lICE9PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSh7IHZpZGVvOiB0cnVlIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFTdWNjZXNzKG1lZGlhU3RyZWFtLCBkZWZpbmVkQXVkaW9Db25zdHJhaW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk5PX0lOUFVUX1NPVVJDRV9TRVQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJQcm9wZXJ0aWVzICdhdWRpb1NvdXJjZScgYW5kICd2aWRlb1NvdXJjZScgY2Fubm90IGJlIHNldCB0byBmYWxzZSBvciBudWxsIGF0IHRoZSBzYW1lIHRpbWUgd2hlbiBjYWxsaW5nICdPcGVuVmlkdS5pbml0UHVibGlzaGVyJ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZWVzdGFibGlzaFN0cmVhbVBsYXlpbmdFdmVudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZWUuZ2V0TGlzdGVuZXJzKCdzdHJlYW1QbGF5aW5nJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5hZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIHNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih3YWl0VGltZTogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkRpYWxvZ1RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEaWFsb2dPcGVuZWQnLCBbXSk7XG4gICAgICAgIH0sIHdhaXRUaW1lKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZTogbnVtYmVyLCB3YWl0VGltZTogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0KTtcbiAgICAgICAgaWYgKChEYXRlLm5vdygpIC0gc3RhcnRUaW1lKSA+IHdhaXRUaW1lKSB7XG4gICAgICAgICAgICAvLyBQZXJtaXNzaW9uIGRpYWxvZyB3YXMgc2hvd24gYW5kIG5vdyBpcyBjbG9zZWRcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEaWFsb2dDbG9zZWQnLCBbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi9GaWx0ZXInO1xuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0NhcGFiaWxpdGllcyc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTaWduYWxPcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TaWduYWxPcHRpb25zJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IE9iak1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL09iak1hcCc7XG5pbXBvcnQgeyBTZXNzaW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1Nlc3Npb25PcHRpb25zJztcbmltcG9ydCB7IENvbm5lY3Rpb25FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0Nvbm5lY3Rpb25FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFJlY29yZGluZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUmVjb3JkaW5nRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50JztcbmltcG9ydCB7IFNpZ25hbEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSB2aWRlbyBjYWxsLiBJdCBjYW4gYWxzbyBiZSBzZWVuIGFzIGEgdmlkZW9jb25mZXJlbmNlIHJvb20gd2hlcmUgbXVsdGlwbGUgdXNlcnMgY2FuIGNvbm5lY3QuXG4gKiBQYXJ0aWNpcGFudHMgd2hvIHB1Ymxpc2ggdGhlaXIgdmlkZW9zIHRvIGEgc2Vzc2lvbiBjYW4gYmUgc2VlbiBieSB0aGUgcmVzdCBvZiB1c2VycyBjb25uZWN0ZWQgdG8gdGhhdCBzcGVjaWZpYyBzZXNzaW9uLlxuICogSW5pdGlhbGl6ZWQgd2l0aCBbW09wZW5WaWR1LmluaXRTZXNzaW9uXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIExvY2FsIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24uIFRoaXMgb2JqZWN0IGlzIGRlZmluZWQgb25seSBhZnRlciBbW1Nlc3Npb24uY29ubmVjdF1dIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBleGVjdXRlZCwgYW5kIGNhbiBiZSByZXRyaWV2ZWQgc3Vic2NyaWJpbmcgdG8gYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgU2Vzc2lvblxuICAgICAqL1xuICAgIHNlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ29sbGVjdGlvbiBvZiBhbGwgU3RyZWFtTWFuYWdlcnMgb2YgdGhpcyBTZXNzaW9uIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSlcbiAgICAgKi9cbiAgICBzdHJlYW1NYW5hZ2VyczogU3RyZWFtTWFuYWdlcltdID0gW107XG5cbiAgICAvKipcbiAgICAgKiBPYmplY3QgZGVmaW5pbmcgdGhlIG1ldGhvZHMgdGhhdCB0aGUgY2xpZW50IGlzIGFibGUgdG8gY2FsbC4gVGhlc2UgYXJlIGRlZmluZWQgYnkgdGhlIHJvbGUgb2YgdGhlIHRva2VuIHVzZWQgdG8gY29ubmVjdCB0byB0aGUgU2Vzc2lvbi5cbiAgICAgKiBUaGlzIG9iamVjdCBpcyBvbmx5IGRlZmluZWQgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVzb2x2ZWRcbiAgICAgKi9cbiAgICBjYXBhYmlsaXRpZXM6IENhcGFiaWxpdGllcztcblxuICAgIC8vIFRoaXMgbWFwIGlzIG9ubHkgdXNlZCB0byBhdm9pZCByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuICdqb2luUm9vbScgcmVzcG9uc2UgYW5kICdvblBhcnRpY2lwYW50UHVibGlzaGVkJyBub3RpZmljYXRpb25cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlU3RyZWFtc0NyZWF0ZWQ6IE9iak1hcDxib29sZWFuPiA9IHt9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdGVDb25uZWN0aW9uczogT2JqTWFwPENvbm5lY3Rpb24+ID0ge307XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgcHJpdmF0ZSBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcGVudmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgdGhpcy5vcGVudmlkdSA9IG9wZW52aWR1O1xuICAgIH1cblxuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PjtcbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcsIG1ldGFkYXRhOiBhbnkpOiBQcm9taXNlPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0cyB0byB0aGUgc2Vzc2lvbiB1c2luZyBgdG9rZW5gLiBQYXJhbWV0ZXIgYG1ldGFkYXRhYCBhbGxvd3MgeW91IHRvIHBhc3MgZXh0cmEgZGF0YSB0byBzaGFyZSB3aXRoIG90aGVyIHVzZXJzIHdoZW5cbiAgICAgKiB0aGV5IHJlY2VpdmUgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50LiBUaGUgc3RydWN0dXJlIG9mIGBtZXRhZGF0YWAgc3RyaW5nIGlzIHVwIHRvIHlvdSAobWF5YmUgc29tZSBzdGFuZGFyZGl6ZWQgZm9ybWF0XG4gICAgICogYXMgSlNPTiBvciBYTUwgaXMgYSBnb29kIGlkZWEpLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRhZGF0YSBpcyBub3QgY29uc2lkZXJlZCBzZWN1cmUsIGFzIGl0IGlzIGdlbmVyYXRlZCBpbiB0aGUgY2xpZW50IHNpZGUuIFRvIHBhc3Mgc2VjdXJlIGRhdGEsIGFkZCBpdCBhcyBhIHBhcmFtZXRlciBpbiB0aGVcbiAgICAgKiB0b2tlbiBnZW5lcmF0aW9uIG9wZXJhdGlvbiAodGhyb3VnaCB0aGUgQVBJIFJFU1QsIG9wZW52aWR1LWphdmEtY2xpZW50IG9yIG9wZW52aWR1LW5vZGUtY2xpZW50KS5cbiAgICAgKlxuICAgICAqIE9ubHkgYWZ0ZXIgdGhlIHJldHVybmVkIFByb21pc2UgaXMgc3VjY2Vzc2Z1bGx5IHJlc29sdmVkIFtbU2Vzc2lvbi5jb25uZWN0aW9uXV0gb2JqZWN0IHdpbGwgYmUgYXZhaWxhYmxlIGFuZCBwcm9wZXJseSBkZWZpbmVkLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBmaXJzdCBkaXNwYXRjaCBvbmUgb3IgbW9yZSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50cyB1cG9uIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhpcyBtZXRob2Q6XG4gICAgICogLSBGaXJzdCBvbmUgZm9yIHlvdXIgb3duIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0LCBzbyB5b3UgY2FuIHJldHJpZXZlIFtbU2Vzc2lvbi5jb25uZWN0aW9uXV0gcHJvcGVydHkuXG4gICAgICogLSBUaGVuIG9uZSBmb3IgZWFjaCByZW1vdGUgQ29ubmVjdGlvbiBwcmV2aW91c2x5IGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiwgaWYgYW55LiBBbnkgb3RoZXIgcmVtb3RlIHVzZXIgY29ubmVjdGluZyB0byB0aGUgU2Vzc2lvbiBhZnRlciB5b3UgaGF2ZVxuICAgICAqIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCB3aGVuIHRoZXkgZG8gc28uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQgZm9yIGVhY2ggcmVtb3RlIGFjdGl2ZSBbW1B1Ymxpc2hlcl1dIHRoYXQgd2FzIGFscmVhZHkgc3RyZWFtaW5nXG4gICAgICogd2hlbiBjb25uZWN0aW5nLCBqdXN0IGFmdGVyIGRpc3BhdGNoaW5nIGFsbCByZW1vdGUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0byB3aGljaCB5b3UgbXVzdCBzdWJzY3JpYmUgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24gd2FzIHN1Y2Nlc3NmdWwgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqXG4gICAgICovXG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YT86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc1Rva2VuKHRva2VuKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMub3BlbnZpZHUuY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKSkge1xuICAgICAgICAgICAgICAgIC8vIEVhcmx5IGNvbmZpZ3VyYXRpb24gdG8gZGVhY3RpdmF0ZSBhdXRvbWF0aWMgc3Vic2NyaXB0aW9uIHRvIHN0cmVhbXNcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHRva2VuLFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogISFtZXRhZGF0YSA/IHRoaXMuc3RyaW5nQ2xpZW50TWV0YWRhdGEobWV0YWRhdGEpIDogJydcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEF1eCh0b2tlbikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5CUk9XU0VSX05PVF9TVVBQT1JURUQsICdCcm93c2VyICcgKyBwbGF0Zm9ybS5uYW1lICsgJyAodmVyc2lvbiAnICsgcGxhdGZvcm0udmVyc2lvbiArICcpIGZvciAnICsgcGxhdGZvcm0ub3MhIS5mYW1pbHkgKyAnIGlzIG5vdCBzdXBwb3J0ZWQgaW4gT3BlblZpZHUnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExlYXZlcyB0aGUgc2Vzc2lvbiwgZGVzdHJveWluZyBhbGwgc3RyZWFtcyBhbmQgZGVsZXRpbmcgdGhlIHVzZXIgYXMgYSBwYXJ0aWNpcGFudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIGxlYXZpbmcgcGFydGljaXBhbnQgZnJvbSBldmVyeSBTdWJzY3JpYmVyIG9iamVjdCBvZiB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gZWFjaCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgdG8gYXZvaWQgdGhpcyBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgYWxsIHRoZSBTdWJzY3JpYmVyIG9iamVjdHMgeW91cnNlbGYuXG4gICAgICogU2VlIFtbU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCBpZiB0aGVyZSBpcyBhIFtbUHVibGlzaGVyXV0gb2JqZWN0IHB1Ymxpc2hpbmcgdG8gdGhlIHNlc3Npb24uXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgc3RvcCBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFB1Ymxpc2hlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHN0cmVhbURlc3Ryb3llZGAgaWYgeW91IHdhbnQgdG8gY2xlYW4gdGhlIFB1Ymxpc2hlciBvYmplY3Qgb24geW91ciBvd24gb3IgcmUtcHVibGlzaCBpdCBpbiBhIGRpZmZlcmVudCBTZXNzaW9uICh0byBkbyBzbyBpdCBpcyBhIG1hbmRhdG9yeSByZXF1aXJlbWVudCB0byBjYWxsIGBTZXNzaW9uLnVucHVibGlzaCgpYFxuICAgICAqIG9yL2FuZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgIGluIHRoZSBwcmV2aW91cyBzZXNzaW9uKS4gU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlIGRpc2Nvbm5lY3RlZCBwYXJ0aWNpcGFudCB3YXMgcHVibGlzaGluZy5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZSB0aGUgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBpbiBhbnkgY2FzZS4gU2VlIFtbQ29ubmVjdGlvbkV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKi9cbiAgICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxlYXZlKGZhbHNlLCAnZGlzY29ubmVjdCcpO1xuICAgIH1cblxuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogU3Vic2NyaWJlcjtcblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gYSBgc3RyZWFtYCwgYWRkaW5nIGEgbmV3IEhUTUwgdmlkZW8gZWxlbWVudCB0byBET00gd2l0aCBgc3Vic2NyaWJlclByb3BlcnRpZXNgIHNldHRpbmdzLiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGNhbGxlZCBpbiB0aGUgY2FsbGJhY2sgb2YgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAgICogW2xldCBPcGVuVmlkdSB0YWtlIGNhcmUgb2YgdGhlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIHJlbW90ZSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RyZWFtIFN0cmVhbSBvYmplY3QgdG8gc3Vic2NyaWJlIHRvXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgU3Vic2NyaWJlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgU3Vic2NyaWJlci5cbiAgICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1N1YnNjcmliZXIuYWRkVmlkZW9FbGVtZW50XV0gb3IgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAgICogQHBhcmFtIGNvbXBsZXRpb25IYW5kbGVyIGBlcnJvcmAgcGFyYW1ldGVyIGlzIG51bGwgaWYgYHN1YnNjcmliZWAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgICAqL1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMz86ICgoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKSB8IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBwYXJhbTQ/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkpOiBTdWJzY3JpYmVyIHtcbiAgICAgICAgbGV0IHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzID0ge307XG4gICAgICAgIGlmICghIXBhcmFtMyAmJiB0eXBlb2YgcGFyYW0zICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6ICh0eXBlb2YgcGFyYW0zLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcGFyYW0zLmluc2VydE1vZGVdIDogcHJvcGVydGllcy5pbnNlcnRNb2RlKSA6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogKHR5cGVvZiBwYXJhbTMuc3Vic2NyaWJlVG9BdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvVmlkZW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvIDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0TW9kZTogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb0F1ZGlvOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvVmlkZW86IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgICAgIGlmICghIXBhcmFtMyAmJiAodHlwZW9mIHBhcmFtMyA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgICAgICB9IGVsc2UgaWYgKCEhcGFyYW00KSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtNDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJpbmcgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgc3RyZWFtLnN1YnNjcmliZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdTdWJzY3JpYmVkIGNvcnJlY3RseSB0byAnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlciA9IG5ldyBTdWJzY3JpYmVyKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyk7XG4gICAgICAgIGlmICghIXN1YnNjcmliZXIudGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgc3RyZWFtLnN0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50KHN1YnNjcmliZXIudGFyZ2V0RWxlbWVudCwgPFZpZGVvSW5zZXJ0TW9kZT5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWJzY3JpYmVyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW1Nlc3Npb24uc3Vic2NyaWJlXV1cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFN1YnNjcmliZXI+O1xuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpOiBQcm9taXNlPFN1YnNjcmliZXI+O1xuXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogU3Vic2NyaWJlclByb3BlcnRpZXMpOiBQcm9taXNlPFN1YnNjcmliZXI+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFN1YnNjcmliZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgbGV0IHN1YnNjcmliZXI6IFN1YnNjcmliZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShzdWJzY3JpYmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmUoc3RyZWFtLCB0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVbnN1YnNjcmliZXMgZnJvbSBgc3Vic2NyaWJlcmAsIGF1dG9tYXRpY2FsbHkgcmVtb3ZpbmcgaXRzIGFzc29jaWF0ZWQgSFRNTCB2aWRlbyBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50IGZvciBlYWNoIHZpZGVvIGFzc29jaWF0ZWQgdG8gaXQgdGhhdCB3YXMgcmVtb3ZlZCBmcm9tIERPTS5cbiAgICAgKiBPbmx5IHZpZGVvcyBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHJlbW92ZWRcbiAgICAgKlxuICAgICAqIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZVxuICAgICAqL1xuICAgIHVuc3Vic2NyaWJlKHN1YnNjcmliZXI6IFN1YnNjcmliZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbklkID0gc3Vic2NyaWJlci5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliaW5nIGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICd1bnN1YnNjcmliZUZyb21WaWRlbycsXG4gICAgICAgICAgICB7IHNlbmRlcjogc3Vic2NyaWJlci5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgfSxcbiAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgdW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1Vuc3Vic2NyaWJlZCBjb3JyZWN0bHkgZnJvbSAnICsgY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyB0byB0aGUgU2Vzc2lvbiB0aGUgUHVibGlzaGVyIG9iamVjdFxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kLiBTZWUgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgbG9jYWwgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBvbmNlIHRoZSBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHNvIHRoZXkgY2FuIHN1YnNjcmliZSB0byBpdC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHB1Ymxpc2hlciB3YXMgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcHVibGlzaChwdWJsaXNoZXI6IFB1Ymxpc2hlcik6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBwdWJsaXNoZXIuc2Vzc2lvbiA9IHRoaXM7XG4gICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnNlc3Npb24gPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoIXB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaGVkT25jZSkge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgTk9UIGJlZW4gY2FsbGVkXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmFkZFN0cmVhbShwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gJ1Nlc3Npb24udW5wdWJsaXNoKFB1Ymxpc2hlciknIGhhcyBiZWVuIGNhbGxlZC4gTXVzdCBpbml0aWFsaXplIGFnYWluIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmFkZFN0cmVhbShwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5yZWVzdGFibGlzaFN0cmVhbVBsYXlpbmdFdmVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5wdWJsaXNoZXMgZnJvbSB0aGUgU2Vzc2lvbiB0aGUgUHVibGlzaGVyIG9iamVjdC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGlzIFB1Ymxpc2hlclxuICAgICAqIChvbmx5IHRob3NlIHZpZGVvcyBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbi5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZSB0aGUgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpIGFuZFxuICAgICAqIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHN0cmVhbURlc3Ryb3llZGAgdG8gYXZvaWQgdGhpcyBkZWZhdWx0IGJlaGF2aW9yIGFuZCB0YWtlIGNhcmUgb2YgZGlzcG9zaW5nIGFuZCBjbGVhbmluZyB0aGUgU3Vic2NyaWJlciBvYmplY3Qgb24geW91ciBvd24uXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKi9cbiAgICB1bnB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBzdHJlYW0gPSBwdWJsaXNoZXIuc3RyZWFtO1xuXG4gICAgICAgIGlmICghc3RyZWFtLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBhc3NvY2lhdGVkIENvbm5lY3Rpb24gb2JqZWN0IG9mIHRoaXMgUHVibGlzaGVyIGlzIG51bGwnLCBzdHJlYW0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2UgaWYgKHN0cmVhbS5jb25uZWN0aW9uICE9PSB0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBhc3NvY2lhdGVkIENvbm5lY3Rpb24gb2JqZWN0IG9mIHRoaXMgUHVibGlzaGVyIGlzIG5vdCB5b3VyIGxvY2FsIENvbm5lY3Rpb24uJyArXG4gICAgICAgICAgICAgICAgXCJPbmx5IG1vZGVyYXRvcnMgY2FuIGZvcmNlIHVucHVibGlzaCBvbiByZW1vdGUgU3RyZWFtcyB2aWEgJ2ZvcmNlVW5wdWJsaXNoJyBtZXRob2RcIiwgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnB1Ymxpc2hpbmcgbG9jYWwgbWVkaWEgKCcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyAnKScpO1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCd1bnB1Ymxpc2hWaWRlbycsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdNZWRpYSB1bnB1Ymxpc2hlZCBjb3JyZWN0bHknKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBkZWxldGUgc3RyZWFtLmNvbm5lY3Rpb24uc3RyZWFtO1xuXG4gICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCBwdWJsaXNoZXIsICdzdHJlYW1EZXN0cm95ZWQnLCBwdWJsaXNoZXIuc3RyZWFtLCAndW5wdWJsaXNoJyk7XG4gICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRm9yY2VzIHNvbWUgdXNlciB0byBsZWF2ZSB0aGUgc2Vzc2lvblxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi5kaXNjb25uZWN0XV0sIGJ1dCBgcmVhc29uYCBwcm9wZXJ0eSBpbiBhbGwgZXZlbnRzIHdpbGwgYmUgYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlIGV2aWN0ZWQgdXNlciB3YXMgcHVibGlzaGluZyBhIHN0cmVhbSwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgZXhjZXB0IHRoZSBldmljdGVkIG9uZSB3aWxsIGRpc3BhdGNoIGEgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50IGZvciB0aGUgZXZpY3RlZCB1c2VyLCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBJZiBhbnksIHRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgZXZpY3RlZCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgZXZpY3RlZCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFNlZSBbW1N0cmVhbUV2ZW50XV0sIFtbQ29ubmVjdGlvbkV2ZW50XV0gYW5kIFtbU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwYXJ0aWNpcGFudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXZpY3RlZCBmcm9tIHRoZSBzZXNzaW9uIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBmb3JjZURpc2Nvbm5lY3QoY29ubmVjdGlvbjogQ29ubmVjdGlvbik6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgZGlzY29ubmVjdCBmb3IgY29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnZm9yY2VEaXNjb25uZWN0JyxcbiAgICAgICAgICAgICAgICB7IGNvbm5lY3Rpb25JZDogY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyBkaXNjb25uZWN0IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBmb3JjZSBhIGRpc2Nvbm5lY3Rpb25cIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgY29ycmVjdGx5IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gdW5wdWJsaXNoIGEgU3RyZWFtXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgd2hlbiBzb21lIHVzZXIgY2FsbHMgW1tTZXNzaW9uLnVucHVibGlzaF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImBcbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgYWZmZWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcmVtb3RlIFN0cmVhbSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VVbnB1Ymxpc2goc3RyZWFtOiBTdHJlYW0pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIHVucHVibGlzaCBmb3Igc3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnZm9yY2VVbnB1Ymxpc2gnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHN0cmVhbS5zdHJlYW1JZCB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBmb3JjaW5nIHVucHVibGlzaCBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYW4gdW5wdWJsaXNoaW5nXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggY29ycmVjdGx5IGZvciBTdHJlYW0gJyArIHN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlbmRzIG9uZSBzaWduYWwuIGBzaWduYWxgIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzOlxuICAgICAqIGBgYGpzb25cbiAgICAgKiB7ZGF0YTpzdHJpbmcsIHRvOkNvbm5lY3Rpb25bXSwgdHlwZTpzdHJpbmd9XG4gICAgICogYGBgXG4gICAgICogQWxsIHVzZXJzIHN1YnNjcmliZWQgdG8gdGhhdCBzaWduYWwgKGBzZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIC4uLilgIG9yIGBzZXNzaW9uLm9uKCdzaWduYWwnLCAuLi4pYCBmb3IgYWxsIHNpZ25hbHMpIGFuZCB3aG9zZSBDb25uZWN0aW9uIG9iamVjdHMgYXJlIGluIGB0b2AgYXJyYXkgd2lsbCByZWNlaXZlIGl0LiBUaGVpciBsb2NhbFxuICAgICAqIFNlc3Npb24gb2JqZWN0cyB3aWxsIGRpc3BhdGNoIGEgYHNpZ25hbGAgb3IgYHNpZ25hbDp0eXBlYCBldmVudC4gU2VlIFtbU2lnbmFsRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBtZXNzYWdlIHN1Y2Nlc3NmdWxseSByZWFjaGVkIG9wZW52aWR1LXNlcnZlciBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90LiBfVGhpcyBkb2Vzbid0XG4gICAgICogbWVhbiB0aGF0IG9wZW52aWR1LXNlcnZlciBjb3VsZCByZXNlbmQgdGhlIG1lc3NhZ2UgdG8gYWxsIHRoZSBsaXN0ZWQgcmVjZWl2ZXJzLl9cbiAgICAgKi9cbiAgICAvKiB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuICAgIHNpZ25hbChzaWduYWw6IFNpZ25hbE9wdGlvbnMpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBzaWduYWxNZXNzYWdlID0ge307XG5cbiAgICAgICAgICAgIGlmIChzaWduYWwudG8gJiYgc2lnbmFsLnRvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uSWRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgc2lnbmFsLnRvLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZHMucHVzaChjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc2lnbmFsTWVzc2FnZVsndG8nXSA9IGNvbm5lY3Rpb25JZHM7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2lnbmFsTWVzc2FnZVsnZGF0YSddID0gc2lnbmFsLmRhdGEgPyBzaWduYWwuZGF0YSA6ICcnO1xuXG4gICAgICAgICAgICBsZXQgdHlwZUF1eDogc3RyaW5nID0gc2lnbmFsLnR5cGUgPyBzaWduYWwudHlwZSA6ICdzaWduYWwnO1xuICAgICAgICAgICAgaWYgKCEhdHlwZUF1eCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlQXV4LnN1YnN0cmluZygwLCA3KSAhPT0gJ3NpZ25hbDonKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVBdXggPSAnc2lnbmFsOicgKyB0eXBlQXV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3R5cGUnXSA9IHR5cGVBdXg7XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3NlbmRNZXNzYWdlJywge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IEpTT04uc3RyaW5naWZ5KHNpZ25hbE1lc3NhZ2UpXG4gICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKiB0c2xpbnQ6ZW5hYmxlOm5vLXN0cmluZy1saXRlcmFsICovXG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB8IFNpZ25hbEV2ZW50IHwgU3RyZWFtRXZlbnQgfCBDb25uZWN0aW9uRXZlbnQgfCBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IHwgUmVjb3JkaW5nRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuXG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgfHwgdHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIHRoaXMuc3BlYWtpbmdFdmVudHNFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcywgZW5hYmxlIGhhcmsgJ3NwZWFraW5nJyBldmVudCBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrIGluIGFsbCBvZiB0aGVtXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBpZiAoISFzdHIgJiYgc3RyLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ci5lbmFibGVPbmNlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vZmZdXVxuICAgICAqL1xuICAgIG9mZih0eXBlOiBzdHJpbmcsIGhhbmRsZXI/OiAoZXZlbnQ6IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB8IFNpZ25hbEV2ZW50IHwgU3RyZWFtRXZlbnQgfCBDb25uZWN0aW9uRXZlbnQgfCBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IHwgUmVjb3JkaW5nRXZlbnQpID0+IHZvaWQpOiBTZXNzaW9uIHtcblxuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGRpc2FibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ci5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRKb2luZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIC8vIENvbm5lY3Rpb24gc2hvdWxkbid0IGV4aXN0XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihyZXNwb25zZS5pZCwgJycpXG5cbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignQ29ubmVjdGlvbiAnICsgcmVzcG9uc2UuaWQgKyAnIGFscmVhZHkgZXhpc3RzIGluIGNvbm5lY3Rpb25zIGxpc3QnKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW3Jlc3BvbnNlLmlkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIGNvbm5lY3Rpb24sICcnKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRMZWZ0KG1zZyk6IHZvaWQge1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24obXNnLmNvbm5lY3Rpb25JZCwgJ1JlbW90ZSBjb25uZWN0aW9uICcgKyBtc2cuY29ubmVjdGlvbklkICsgXCIgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50TGVmdCcuIFwiICtcbiAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG5cbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBzdHJlYW0sIG1zZy5yZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvdW50RG93bkZvcklvbmljSW9zU3Vic2NyaWJlcnMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ucmVtb3ZlU3RyZWFtKHN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50RXZpY3RlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb25JZCAmJiAhdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWF2ZSh0cnVlLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk5ld01lc3NhZ2UobXNnKTogdm9pZCB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCdOZXcgc2lnbmFsOiAnICsgSlNPTi5zdHJpbmdpZnkobXNnKSk7XG5cbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5mcm9tLCBcIkNvbm5lY3Rpb24gJ1wiICsgbXNnLmZyb20gKyBcIicgdW5rbm93IHdoZW4gJ29uTmV3TWVzc2FnZScuIEV4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogXCJcbiAgICAgICAgICAgICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpICsgJy4gRXhpc3RpbmcgbG9jYWwgY29ubmVjdGlvbjogJyArIHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpXG5cbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzaWduYWwnLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIG1zZy50eXBlLCBtc2cuZGF0YSwgY29ubmVjdGlvbildKTtcbiAgICAgICAgICAgICAgICBpZiAobXNnLnR5cGUgIT09ICdzaWduYWwnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KG1zZy50eXBlLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIG1zZy50eXBlLCBtc2cuZGF0YSwgY29ubmVjdGlvbildKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQobXNnKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoY29ubmVjdGlvbjogQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbi5zdHJlYW0gJiYgY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQgPT09IG1zZy5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGxldCBvbGRWYWx1ZTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG1zZy5wcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhdWRpb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5hdWRpb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmF1ZGlvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvQWN0aXZlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLnZpZGVvQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgbXNnLm5ld1ZhbHVlID0gbXNnLm5ld1ZhbHVlID09PSAndHJ1ZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9BY3RpdmUgPSBtc2cubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndmlkZW9EaW1lbnNpb25zJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLnZpZGVvRGltZW5zaW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IEpTT04ucGFyc2UoSlNPTi5wYXJzZShtc2cubmV3VmFsdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSBtc2cubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmlsdGVyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IChPYmplY3Qua2V5cyhtc2cubmV3VmFsdWUpLmxlbmd0aCA+IDApID8gbXNnLm5ld1ZhbHVlIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlciA9IG5ldyBGaWx0ZXIobXNnLm5ld1ZhbHVlLnR5cGUsIG1zZy5uZXdWYWx1ZS5vcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIubGFzdEV4ZWNNZXRob2QgPSBtc2cubmV3VmFsdWUubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc3RyZWFtLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHN0cmVhbS5zdHJlYW1NYW5hZ2VyLCBzdHJlYW0sIG1zZy5wcm9wZXJ0eSwgbXNnLm5ld1ZhbHVlLCBvbGRWYWx1ZSwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJObyBzdHJlYW0gd2l0aCBzdHJlYW1JZCAnXCIgKyBtc2cuc3RyZWFtSWQgKyBcIicgZm91bmQgZm9yIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyBvbiAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgY2hhbmdlZCAoZmlsdGVyIGZlYXR1cmUpXG4gICAgICAgICAgICBjYWxsYmFjayh0aGlzLmNvbm5lY3Rpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcbiAgICAgICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjdkljZUNhbmRpZGF0ZShtc2cpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSB7XG4gICAgICAgICAgICBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUsXG4gICAgICAgICAgICBjb21wb25lbnQ6IG1zZy5jb21wb25lbnQsXG4gICAgICAgICAgICBmb3VuZGF0aW9uOiBtc2cuZm91bmRhdGlvbixcbiAgICAgICAgICAgIGlwOiBtc2cuaXAsXG4gICAgICAgICAgICBwb3J0OiBtc2cucG9ydCxcbiAgICAgICAgICAgIHByaW9yaXR5OiBtc2cucHJpb3JpdHksXG4gICAgICAgICAgICBwcm90b2NvbDogbXNnLnByb3RvY29sLFxuICAgICAgICAgICAgcmVsYXRlZEFkZHJlc3M6IG1zZy5yZWxhdGVkQWRkcmVzcyxcbiAgICAgICAgICAgIHJlbGF0ZWRQb3J0OiBtc2cucmVsYXRlZFBvcnQsXG4gICAgICAgICAgICBzZHBNaWQ6IG1zZy5zZHBNaWQsXG4gICAgICAgICAgICBzZHBNTGluZUluZGV4OiBtc2cuc2RwTUxpbmVJbmRleCxcbiAgICAgICAgICAgIHRjcFR5cGU6IG1zZy50Y3BUeXBlLFxuICAgICAgICAgICAgdXNlcm5hbWVGcmFnbWVudDogbXNnLnVzZXJuYW1lRnJhZ21lbnQsXG4gICAgICAgICAgICB0eXBlOiBtc2cudHlwZSxcbiAgICAgICAgICAgIHRvSlNPTjogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IGNhbmRpZGF0ZTogbXNnLmNhbmRpZGF0ZSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24obXNnLnNlbmRlckNvbm5lY3Rpb25JZCwgJ0Nvbm5lY3Rpb24gbm90IGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIG1zZy5zZW5kZXJDb25uZWN0aW9uSWQgKyAnIG93bmluZyBlbmRwb2ludCAnICsgbXNnLmVuZHBvaW50TmFtZSArICcuIEljZSBjYW5kaWRhdGUgd2lsbCBiZSBpZ25vcmVkOiAnICsgY2FuZGlkYXRlKVxuICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG4gICAgICAgICAgICAgICAgc3RyZWFtLmdldFdlYlJ0Y1BlZXIoKS5hZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGFkZGluZyBjYW5kaWRhdGUgZm9yICcgKyBzdHJlYW0uc3RyZWFtSWRcbiAgICAgICAgICAgICAgICAgICAgICAgICsgJyBzdHJlYW0gb2YgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnOiAnICsgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU2Vzc2lvbkNsb3NlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5pbmZvKCdTZXNzaW9uIGNsb3NlZDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuICAgICAgICBjb25zdCBzID0gbXNnLnNlc3Npb25JZDtcbiAgICAgICAgaWYgKHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3Nlc3Npb24tY2xvc2VkJywgW3tcbiAgICAgICAgICAgICAgICBzZXNzaW9uOiBzXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1Nlc3Npb24gdW5kZWZpbmVkIG9uIHNlc3Npb24gY2xvc2VkJywgbXNnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkxvc3RDb25uZWN0aW9uKHJlYXNvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignTG9zdCBjb25uZWN0aW9uIGluIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkICsgJyB3YWl0aW5nIGZvciByZWNvbm5lY3QnKTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgdGhpcy5sZWF2ZSh0cnVlLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdSZWNvdmVyZWQgY29ubmVjdGlvbiBpbiBTZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCk7XG4gICAgICAgIC8vIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uUmVjb3ZlcmVkJywgW10pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk1lZGlhRXJyb3IocGFyYW1zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWEgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgY29uc3QgZXJyID0gcGFyYW1zLmVycm9yO1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnZXJyb3ItbWVkaWEnLCBbe1xuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJcbiAgICAgICAgICAgIH1dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgdW5kZWZpbmVkIG1lZGlhIGVycm9yLiBQYXJhbXM6JywgcGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0YXJ0ZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0YXJ0ZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdGFydGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUpXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUmVjb3JkaW5nU3RvcHBlZChyZXNwb25zZSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb3JkaW5nU3RvcHBlZCcsIFtuZXcgUmVjb3JkaW5nRXZlbnQodGhpcywgJ3JlY29yZGluZ1N0b3BwZWQnLCByZXNwb25zZS5pZCwgcmVzcG9uc2UubmFtZSwgcmVzcG9uc2UucmVhc29uKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKiByZXNwb25zZSA9IHtjb25uZWN0aW9uSWQ6IHN0cmluZywgc3RyZWFtSWQ6IHN0cmluZywgdHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3R9XG4gICAgICovXG4gICAgb25GaWx0ZXJFdmVudERpc3BhdGNoZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbklkOiBzdHJpbmcgPSByZXNwb25zZS5jb25uZWN0aW9uSWQ7XG4gICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSByZXNwb25zZS5zdHJlYW1JZDtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKGNvbm5lY3Rpb25JZCwgJ05vIGNvbm5lY3Rpb24gZm91bmQgZm9yIGNvbm5lY3Rpb25JZCAnICsgY29ubmVjdGlvbklkKVxuICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgZGlzcGF0Y2hlZCcpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbTogU3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG4gICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5oYW5kbGVyc1tyZXNwb25zZS5ldmVudFR5cGVdKG5ldyBGaWx0ZXJFdmVudChzdHJlYW0uZmlsdGVyLCByZXNwb25zZS5ldmVudFR5cGUsIHJlc3BvbnNlLmRhdGEpKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGVhdmUoZm9yY2VkOiBib29sZWFuLCByZWFzb246IHN0cmluZyk6IHZvaWQge1xuXG4gICAgICAgIGZvcmNlZCA9ICEhZm9yY2VkO1xuICAgICAgICBjb25zb2xlLmluZm8oJ0xlYXZpbmcgU2Vzc2lvbiAoZm9yY2VkPScgKyBmb3JjZWQgKyAnKScpO1xuXG4gICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbikge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQgJiYgIWZvcmNlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2xlYXZlUm9vbScsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmNsb3NlV3MoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShyZWFzb24pO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIC8vIE1ha2UgU2Vzc2lvbiBvYmplY3QgZGlzcGF0Y2ggJ3Nlc3Npb25EaXNjb25uZWN0ZWQnIGV2ZW50IChpZiBpdCBpcyBub3QgYWxyZWFkeSBkaXNwb3NlZClcbiAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uRGlzY29ubmVjdEV2ZW50ID0gbmV3IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCh0aGlzLCByZWFzb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uRGlzY29ubmVjdGVkJywgW3Nlc3Npb25EaXNjb25uZWN0RXZlbnRdKTtcbiAgICAgICAgICAgICAgICBzZXNzaW9uRGlzY29ubmVjdEV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignWW91IHdlcmUgbm90IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgY29ubmVjdEF1eCh0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc3RhcnRXcygoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgam9pblBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiAoISF0b2tlbikgPyB0b2tlbiA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbjogdGhpcy5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybTogISFwbGF0Zm9ybS5kZXNjcmlwdGlvbiA/IHBsYXRmb3JtLmRlc2NyaXB0aW9uIDogJ3Vua25vd24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhdGhpcy5vcHRpb25zLm1ldGFkYXRhID8gdGhpcy5vcHRpb25zLm1ldGFkYXRhIDogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWNyZXQ6IHRoaXMub3BlbnZpZHUuZ2V0U2VjcmV0KCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRlcjogdGhpcy5vcGVudmlkdS5nZXRSZWNvcmRlcigpXG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgnam9pblJvb20nLCBqb2luUGFyYW1zLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBjYXBhYmlsaXRpZXMgb2JqZWN0IHdpdGggdGhlIHJvbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhcGFiaWxpdGllcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgIT09ICdTVUJTQ1JJQkVSJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yY2VVbnB1Ymxpc2g6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlRGlzY29ubmVjdDogdGhpcy5vcGVudmlkdS5yb2xlID09PSAnTU9ERVJBVE9SJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0IHdpdGggdmFsdWVzIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgPSByZXNwb25zZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5kYXRhID0gcmVzcG9uc2UubWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnJwY1Nlc3Npb25JZCA9IHJlc3BvbnNlLnNlc3Npb25JZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgcmVtb3RlIENvbm5lY3Rpb25zIHdpdGggdmFsdWUgcmV0dXJuZWQgYnkgb3BlbnZpZHUtc2VydmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uczogbmV3IEFycmF5PENvbm5lY3Rpb24+KCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXM6IG5ldyBBcnJheTxTdHJlYW0+KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nUGFydGljaXBhbnRzOiBDb25uZWN0aW9uT3B0aW9uc1tdID0gcmVzcG9uc2UudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdQYXJ0aWNpcGFudHMuZm9yRWFjaChwYXJ0aWNpcGFudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCBwYXJ0aWNpcGFudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuc3RyZWFtcy5wdXNoKGNvbm5lY3Rpb24uc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3duICdjb25uZWN0aW9uQ3JlYXRlZCcgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25DcmVhdGVkJywgdGhpcy5jb25uZWN0aW9uLCAnJyldKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50IGZvciBlYWNoIGV4aXN0aW5nIGNvbm5lY3Rpb24gaW4gdGhlIHNlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuY29ubmVjdGlvbnMuZm9yRWFjaChjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIGNvbm5lY3Rpb24sICcnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lICdzdHJlYW1DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBhY3RpdmUgc3RyZWFtIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMuZm9yRWFjaChzdHJlYW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcFB1Ymxpc2hlclN0cmVhbShyZWFzb246IHN0cmluZykge1xuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAvLyBEaXNwb3NlIFB1Ymxpc2hlcidzICBsb2NhbCBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFB1Ymxpc2hlciBvYmplY3QgZGlzcGF0Y2ggJ3N0cmVhbURlc3Ryb3llZCcgZXZlbnQgaWYgdGhlIFN0cmVhbSB3YXMgcHVibGlzaGVkXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCBbcmVhc29uXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhOiBhbnkpOiBzdHJpbmcge1xuICAgICAgICBpZiAodHlwZW9mIG1ldGFkYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQ6IHN0cmluZywgZXJyb3JNZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPENvbm5lY3Rpb24+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPENvbm5lY3Rpb24+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSByZW1vdGUgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgIHJlc29sdmUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID09PSBjb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSBsb2NhbCBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBDb25uZWN0aW9uIG5vdCBmb3VuZC4gUmVqZWN0IHdpdGggT3BlblZpZHVFcnJvclxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlbW90ZUNvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdGUgY29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJvY2Vzc1Rva2VuKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB0b2tlbi5tYXRjaCgvXih3c3M/XFw6KVxcL1xcLygoW146XFwvPyNdKikoPzpcXDooWzAtOV0rKSk/KShbXFwvXXswLDF9W14/I10qKShcXD9bXiNdKnwpKCMuKnwpJC8pO1xuICAgICAgICBpZiAoISFtYXRjaCkge1xuICAgICAgICAgICAgY29uc3QgdXJsID0ge1xuICAgICAgICAgICAgICAgIHByb3RvY29sOiBtYXRjaFsxXSxcbiAgICAgICAgICAgICAgICBob3N0OiBtYXRjaFsyXSxcbiAgICAgICAgICAgICAgICBob3N0bmFtZTogbWF0Y2hbM10sXG4gICAgICAgICAgICAgICAgcG9ydDogbWF0Y2hbNF0sXG4gICAgICAgICAgICAgICAgcGF0aG5hbWU6IG1hdGNoWzVdLFxuICAgICAgICAgICAgICAgIHNlYXJjaDogbWF0Y2hbNl0sXG4gICAgICAgICAgICAgICAgaGFzaDogbWF0Y2hbN11cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRva2VuLnNwbGl0KCc/Jyk7XG4gICAgICAgICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IGRlY29kZVVSSShwYXJhbXNbMV0pXG4gICAgICAgICAgICAgICAgLnNwbGl0KCcmJylcbiAgICAgICAgICAgICAgICAubWFwKHBhcmFtID0+IHBhcmFtLnNwbGl0KCc9JykpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgodmFsdWVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2tleV0gPSB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzXG4gICAgICAgICAgICAgICAgfSwge30pO1xuXG4gICAgICAgICAgICB0aGlzLnNlc3Npb25JZCA9IDxzdHJpbmc+cXVlcnlQYXJhbXNbJ3Nlc3Npb25JZCddO1xuICAgICAgICAgICAgY29uc3Qgc2VjcmV0ID0gcXVlcnlQYXJhbXNbJ3NlY3JldCddO1xuICAgICAgICAgICAgY29uc3QgcmVjb3JkZXIgPSBxdWVyeVBhcmFtc1sncmVjb3JkZXInXTtcbiAgICAgICAgICAgIGNvbnN0IHR1cm5Vc2VybmFtZSA9IHF1ZXJ5UGFyYW1zWyd0dXJuVXNlcm5hbWUnXTtcbiAgICAgICAgICAgIGNvbnN0IHR1cm5DcmVkZW50aWFsID0gcXVlcnlQYXJhbXNbJ3R1cm5DcmVkZW50aWFsJ107XG4gICAgICAgICAgICBjb25zdCByb2xlID0gcXVlcnlQYXJhbXNbJ3JvbGUnXTtcbiAgICAgICAgICAgIGNvbnN0IHdlYnJ0Y1N0YXRzSW50ZXJ2YWwgPSBxdWVyeVBhcmFtc1snd2VicnRjU3RhdHNJbnRlcnZhbCddO1xuICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uID0gcXVlcnlQYXJhbXNbJ3ZlcnNpb24nXTtcblxuICAgICAgICAgICAgaWYgKCEhc2VjcmV0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZWNyZXQgPSBzZWNyZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFyZWNvcmRlcikge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucmVjb3JkZXIgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhdHVyblVzZXJuYW1lICYmICEhdHVybkNyZWRlbnRpYWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHVuVXJsID0gJ3N0dW46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDEgPSAndHVybjonICsgdXJsLmhvc3RuYW1lICsgJzozNDc4JztcbiAgICAgICAgICAgICAgICBjb25zdCB0dXJuVXJsMiA9IHR1cm5VcmwxICsgJz90cmFuc3BvcnQ9dGNwJztcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmljZVNlcnZlcnMgPSBbXG4gICAgICAgICAgICAgICAgICAgIHsgdXJsczogW3N0dW5VcmxdIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgdXJsczogW3R1cm5VcmwxLCB0dXJuVXJsMl0sIHVzZXJuYW1lOiB0dXJuVXNlcm5hbWUsIGNyZWRlbnRpYWw6IHR1cm5DcmVkZW50aWFsIH1cbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdUVVJOIHRlbXAgY3JlZGVudGlhbHMgWycgKyB0dXJuVXNlcm5hbWUgKyAnOicgKyB0dXJuQ3JlZGVudGlhbCArICddJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFyb2xlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5yb2xlID0gcm9sZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXdlYnJ0Y1N0YXRzSW50ZXJ2YWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgPSArd2VicnRjU3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIW9wZW52aWR1U2VydmVyVmVyc2lvbikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIm9wZW52aWR1LXNlcnZlciB2ZXJzaW9uOiBcIiArIG9wZW52aWR1U2VydmVyVmVyc2lvbik7XG4gICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1U2VydmVyVmVyc2lvbiAhPT0gdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdPcGVuVmlkdSBTZXJ2ZXIgKCcgKyBvcGVudmlkdVNlcnZlclZlcnNpb24gK1xuICAgICAgICAgICAgICAgICAgICAgICAgJykgYW5kIE9wZW5WaWR1IEJyb3dzZXIgKCcgKyB0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIHZlcnNpb25zIGRvIE5PVCBtYXRjaC4gVGhlcmUgbWF5IGJlIGluY29tcGF0aWJpbGl0aWVzJylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUud3NVcmkgPSAnd3NzOi8vJyArIHVybC5ob3N0ICsgJy9vcGVudmlkdSc7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1Lmh0dHBVcmkgPSAnaHR0cHM6Ly8nICsgdXJsLmhvc3Q7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Rva2VuIFwiJyArIHRva2VuICsgJ1wiIGlzIG5vdCB2YWxpZCcpXG4gICAgICAgIH1cbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4vQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyIH0gZnJvbSAnLi9TdWJzY3JpYmVyJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgT3V0Ym91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvT3V0Ym91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IFdlYlJ0Y1BlZXIsIFdlYlJ0Y1BlZXJTZW5kb25seSwgV2ViUnRjUGVlclJlY3Zvbmx5LCBXZWJSdGNQZWVyU2VuZHJlY3YgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1BlZXIvV2ViUnRjUGVlcic7XG5pbXBvcnQgeyBXZWJSdGNTdGF0cyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvV2ViUnRjU3RhdHMvV2ViUnRjU3RhdHMnO1xuaW1wb3J0IHsgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1B1Ymxpc2hlclNwZWFraW5nRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBoYXJrID0gcmVxdWlyZSgnaGFyaycpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuXG4vKipcbiAqIFJlcHJlc2VudHMgZWFjaCBvbmUgb2YgdGhlIG1lZGlhIHN0cmVhbXMgYXZhaWxhYmxlIGluIE9wZW5WaWR1IFNlcnZlciBmb3IgY2VydGFpbiBzZXNzaW9uLlxuICogRWFjaCBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSBoYXMgYW4gYXR0cmlidXRlIG9mIHR5cGUgU3RyZWFtLCBhcyB0aGV5IGdpdmUgYWNjZXNzXG4gKiB0byBvbmUgb2YgdGhlbSAoc2VuZGluZyBhbmQgcmVjZWl2aW5nIGl0LCByZXNwZWN0aXZlbHkpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW0gaW1wbGVtZW50cyBFdmVudERpc3BhdGNoZXIge1xuXG4gICAgLyoqXG4gICAgICogVGhlIENvbm5lY3Rpb24gb2JqZWN0IHRoYXQgaXMgcHVibGlzaGluZyB0aGUgc3RyZWFtXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEZyYW1lIHJhdGUgb2YgdGhlIHZpZGVvIGluIGZyYW1lcyBwZXIgc2Vjb25kLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZiB0aGUgW1tQdWJsaXNoZXJdXSBvZlxuICAgICAqIHRoZSBzdHJlYW0gd2FzIGluaXRpYWxpemVkIHBhc3NpbmcgYSBfZnJhbWVSYXRlXyBwcm9wZXJ0eSBvbiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBtZXRob2RcbiAgICAgKi9cbiAgICBmcmFtZVJhdGU/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIGEgdmlkZW8gdHJhY2sgb3Igbm90XG4gICAgICovXG4gICAgaGFzVmlkZW86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIGFuIGF1ZGlvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc0F1ZGlvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyB0aGUgdmlkZW8gdHJhY2sgbXV0ZWQgb3IgdW5tdXRlZC4gSWYgW1toYXNWaWRlb11dIGlzIGZhbHNlLCB0aGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbSBjYWxscyBbW1B1Ymxpc2hlci5wdWJsaXNoVmlkZW9dXS4gV2hlbmV2ZXIgdGhpcyBoYXBwZW5zIGEgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHdpbGwgYmUgZGlzcGF0Y2hlZFxuICAgICAqIGJ5IHRoZSBTZXNzaW9uIG9iamVjdCBhcyB3ZWxsIGFzIGJ5IHRoZSBhZmZlY3RlZCBTdWJzY3JpYmVyL1B1Ymxpc2hlciBvYmplY3RcbiAgICAgKi9cbiAgICB2aWRlb0FjdGl2ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIGF1ZGlvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzQXVkaW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbSBjYWxscyBbW1B1Ymxpc2hlci5wdWJsaXNoQXVkaW9dXS4gV2hlbmV2ZXIgdGhpcyBoYXBwZW5zIGEgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHdpbGwgYmUgZGlzcGF0Y2hlZFxuICAgICAqIGJ5IHRoZSBTZXNzaW9uIG9iamVjdCBhcyB3ZWxsIGFzIGJ5IHRoZSBhZmZlY3RlZCBTdWJzY3JpYmVyL1B1Ymxpc2hlciBvYmplY3RcbiAgICAgKi9cbiAgICBhdWRpb0FjdGl2ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBzdHJlYW0uIElmIHRoZSBzdHJlYW0gYmVsb25ncyB0byBhLi4uXG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYHN0cmVhbUlkYCBpcyBhbHdheXMgZGVmaW5lZFxuICAgICAqIC0gUHVibGlzaGVyIG9iamVjdDogcHJvcGVydHkgYHN0cmVhbUlkYCBpcyBvbmx5IGRlZmluZWQgYWZ0ZXIgc3VjY2Vzc2Z1bCBleGVjdXRpb24gb2YgW1tTZXNzaW9uLnB1Ymxpc2hdXVxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaW1lIHdoZW4gdGhpcyBzdHJlYW0gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKS4gRGVwZW5kaW5nIG9uIHRoZSBvd25lciBvZiB0aGlzIHN0cmVhbTpcbiAgICAgKiAtIFN1YnNjcmliZXIgb2JqZWN0OiBwcm9wZXJ0eSBgY3JlYXRpb25UaW1lYCBpcyBhbHdheXMgZGVmaW5lZFxuICAgICAqIC0gUHVibGlzaGVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBjcmVhdGlvblRpbWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIGBcIkNBTUVSQVwiYCwgYFwiU0NSRUVOXCJgIG9yIGBcIkNVU1RPTVwiYCAodGhlIGxhdHRlciB3aGVuIFtbUHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZV1dIGlzIGEgTWVkaWFTdHJlYW1UcmFjayB3aGVuIGNhbGxpbmcgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0pLlxuICAgICAqIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKi9cbiAgICB0eXBlT2ZWaWRlbz86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbU1hbmFnZXIgb2JqZWN0IChbW1B1Ymxpc2hlcl1dIG9yIFtbU3Vic2NyaWJlcl1dKSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGlzIHN0cmVhbSBpbiB0aGUgRE9NXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcjogU3RyZWFtTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFdpZHRoIGFuZCBoZWlnaHQgaW4gcGl4ZWxzIG9mIHRoZSBlbmNvZGVkIHZpZGVvIHN0cmVhbS4gSWYgW1toYXNWaWRlb11dIGlzIGZhbHNlLCB0aGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZFxuICAgICAqXG4gICAgICogVGhpcyBwcm9wZXJ0eSBtYXkgY2hhbmdlIGlmIHRoZSBQdWJsaXNoZXIgdGhhdCBpcyBwdWJsaXNoaW5nOlxuICAgICAqIC0gSWYgaXQgaXMgYSBtb2JpbGUgZGV2aWNlLCB3aGVuZXZlciB0aGUgdXNlciByb3RhdGVzIHRoZSBkZXZpY2UuXG4gICAgICogLSBJZiBpdCBpcyBzY3JlZW4tc2hhcmluZywgd2hlbmV2ZXIgdGhlIHVzZXIgY2hhbmdlcyB0aGUgc2l6ZSBvZiB0aGUgY2FwdHVyZWQgd2luZG93LlxuICAgICAqXG4gICAgICogV2hlbmV2ZXIgdGhpcyBoYXBwZW5zIGEgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHdpbGwgYmUgZGlzcGF0Y2hlZCBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9EaW1lbnNpb25zOiB7IHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyIH07XG5cbiAgICAvKipcbiAgICAgKiAqKldBUk5JTkcqKjogZXhwZXJpbWVudGFsIG9wdGlvbi4gVGhpcyBpbnRlcmZhY2UgbWF5IGNoYW5nZSBpbiB0aGUgbmVhciBmdXR1cmVcbiAgICAgKlxuICAgICAqIEZpbHRlciBhcHBsaWVkIHRvIHRoZSBTdHJlYW0uIFlvdSBjYW4gYXBwbHkgZmlsdGVycyBieSBjYWxsaW5nIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIGV4ZWN1dGUgbWV0aG9kcyBvZiB0aGUgYXBwbGllZCBmaWx0ZXIgd2l0aFxuICAgICAqIFtbRmlsdGVyLmV4ZWNNZXRob2RdXSBhbmQgcmVtb3ZlIGl0IHdpdGggW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV0uIEJlIGF3YXJlIHRoYXQgdGhlIGNsaWVudCBjYWxsaW5nIHRoaXMgbWV0aG9kcyBtdXN0IGhhdmUgdGhlXG4gICAgICogbmVjZXNzYXJ5IHBlcm1pc3Npb25zOiB0aGUgdG9rZW4gb3duZWQgYnkgdGhlIGNsaWVudCBtdXN0IGhhdmUgYmVlbiBpbml0aWFsaXplZCB3aXRoIHRoZSBhcHByb3ByaWF0ZWQgYGFsbG93ZWRGaWx0ZXJzYCBhcnJheS5cbiAgICAgKi9cbiAgICBmaWx0ZXI6IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIHByaXZhdGUgd2ViUnRjUGVlcjogV2ViUnRjUGVlcjtcbiAgICBwcml2YXRlIG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbTtcbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzOiBXZWJSdGNTdGF0cztcblxuICAgIHByaXZhdGUgaXNTdWJzY3JpYmVUb1JlbW90ZSA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5ib3VuZFN0cmVhbU9wdHM6IEluYm91bmRTdHJlYW1PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvdXRib3VuZFN0cmVhbU9wdHM6IE91dGJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3BlZWNoRXZlbnQ6IGFueTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzZXNzaW9uOiBTZXNzaW9uLCBvcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyB8IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB8IHt9KSB7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uID0gc2Vzc2lvbjtcblxuICAgICAgICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnaWQnKSkge1xuICAgICAgICAgICAgLy8gSW5ib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgU3Vic2NyaWJlclxuICAgICAgICAgICAgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cyA9IDxJbmJvdW5kU3RyZWFtT3B0aW9ucz5vcHRpb25zO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaWQ7XG4gICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuY3JlYXRlZEF0O1xuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW87XG4gICAgICAgICAgICB0aGlzLmhhc1ZpZGVvID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNWaWRlbztcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLnZpZGVvQWN0aXZlO1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZU9mVmlkZW8gPSAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW8pID8gdW5kZWZpbmVkIDogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy50eXBlT2ZWaWRlbztcbiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lUmF0ZSA9ICh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZyYW1lUmF0ZSA9PT0gLTEpID8gdW5kZWZpbmVkIDogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0RpbWVuc2lvbnMgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLnZpZGVvRGltZW5zaW9ucztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZmlsdGVyICYmIChPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcikubGVuZ3RoID4gMCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCAmJiBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE91dGJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBQdWJsaXNoZXJcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gPE91dGJvdW5kU3RyZWFtT3B0aW9ucz5vcHRpb25zO1xuXG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pc1NlbmRBdWRpbygpO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaXNTZW5kVmlkZW8oKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHlwZU9mVmlkZW8gPSAnQ1VTVE9NJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gdGhpcy5pc1NlbmRTY3JlZW4oKSA/ICdTQ1JFRU4nIDogJ0NBTUVSQSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5maWx0ZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlciA9IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lZS5vbignbWVkaWFzdHJlYW0tdXBkYXRlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci51cGRhdGVNZWRpYVN0cmVhbSh0aGlzLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1ZpZGVvIHNyY09iamVjdCBbJyArIHRoaXMubWVkaWFTdHJlYW0gKyAnXSB1cGRhdGVkIGluIHN0cmVhbSBbJyArIHRoaXMuc3RyZWFtSWQgKyAnXScpO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5IHN0cmVhbSAnXCIgKyB0aGlzLnN0cmVhbUlkICsgXCInXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlIGJ5IHN0cmVhbSAnXCIgKyB0aGlzLnN0cmVhbUlkICsgXCInXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5lZS5yZW1vdmVBbGxMaXN0ZW5lcnModHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmVlLm9mZih0eXBlLCBoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHRvIHRoZSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGZpbHRlciBhcHBsaWVkLiBTZWUgW1tGaWx0ZXIudHlwZV1dXG4gICAgICogQHBhcmFtIG9wdGlvbnMgUGFyYW1ldGVycyB1c2VkIHRvIGluaXRpYWxpemUgdGhlIGZpbHRlci4gU2VlIFtbRmlsdGVyLm9wdGlvbnNdXVxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHRvIHRoZSBhcHBsaWVkIGZpbHRlciBpZiBzdWNjZXNzIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhcHBseUZpbHRlcih0eXBlOiBzdHJpbmcsIG9wdGlvbnM6IE9iamVjdCk6IFByb21pc2U8RmlsdGVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0FwcGx5aW5nIGZpbHRlciB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgb3B0aW9ucyA9ICEhb3B0aW9ucyA/IG9wdGlvbnMgOiB7fTtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gSlNPTi5zdHJpbmdpZnkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FwcGx5RmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkLCB0eXBlLCBvcHRpb25zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGFwcGx5aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFwcGx5IGEgZmlsdGVyXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIHN1Y2Nlc3NmdWxseSBhcHBsaWVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZTogRmlsdGVyID0gdGhpcy5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIodHlwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlci5zdHJlYW0gPSB0aGlzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbiBhdWRpby92aWRlbyBmaWx0ZXIgcHJldmlvdXNseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBwcmV2aW91c2x5IGFwcGxpZWQgZmlsdGVyIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpbiBvdGhlciBjYXNlXG4gICAgICovXG4gICAgcmVtb3ZlRmlsdGVyKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ1JlbW92aW5nIGZpbHRlciBvZiBzdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdyZW1vdmVGaWx0ZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVtb3ZpbmcgZmlsdGVyIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcmVtb3ZlIGEgZmlsdGVyXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGZyb20gU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRNZWRpYVN0cmVhbSgpOiBNZWRpYVN0cmVhbSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lZGlhU3RyZWFtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXRNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG1lZGlhU3RyZWFtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCkge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnbWVkaWFzdHJlYW0tdXBkYXRlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0V2ViUnRjUGVlcigpOiBXZWJSdGNQZWVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UlRDUGVlckNvbm5lY3Rpb24oKTogUlRDUGVlckNvbm5lY3Rpb24ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNTdWJzY3JpYmVUb1JlbW90ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPSBvdXRib3VuZFN0cmVhbU9wdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN1YnNjcmliZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmUoKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2goKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJTZW5kKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUub25jZSgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZVdlYlJ0Y1BlZXIoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0b3BXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdPdXRib3VuZCAnIDogJ0luYm91bmQgJykgKyBcIldlYlJUQ1BlZXIgZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgY2xvc2VkJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VNZWRpYVN0cmVhbSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnTG9jYWwgJyA6ICdSZW1vdGUgJykgKyBcIk1lZGlhU3RyZWFtIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGRpc3Bvc2VkJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3BsYXlNeVJlbW90ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTdWJzY3JpYmVUb1JlbW90ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kQXVkaW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRWaWRlbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFNjcmVlbigpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IHNjcmVlbiA9IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nO1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ0VsZWN0cm9uJykge1xuICAgICAgICAgICAgc2NyZWVuID0gdHlwZW9mIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiYgc2NyZWVuO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhcmtPcHRpb25zID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMgfHwge307XG4gICAgICAgICAgICBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9ICh0eXBlb2YgaGFya09wdGlvbnMuaW50ZXJ2YWwgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLmludGVydmFsIDogNTA7XG4gICAgICAgICAgICBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPSAodHlwZW9mIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMudGhyZXNob2xkIDogLTUwO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudCA9IGhhcmsodGhpcy5tZWRpYVN0cmVhbSwgaGFya09wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnIGV2ZW50IGlzIGVuYWJsZWQuIENhbm5vdCBzdG9wIHRoZSBoYXJrIHByb2Nlc3NcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZignc3BlYWtpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZignc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBhbmQvb3IgcHVibGlzaGVyU3RvcFNwZWFraW5nYCBldmVudHMgYXJlIGVuYWJsZWQuIENhbm5vdCBzdG9wIHRoZSBoYXJrIHByb2Nlc3NcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZigndm9sdW1lX2NoYW5nZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBpbmJvdW5kIG9wdGlvbnMgdW5kZWZpbmVkIGFuZCBvdXRib3VuZCBvcHRpb25zIGRlZmluZWRcbiAgICAgICAgcmV0dXJuICghdGhpcy5pbmJvdW5kU3RyZWFtT3B0cyAmJiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHMuZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKClcbiAgICAgICAgICAgICAgICAudGhlbihyZXBvcnQgPT4gcmVzb2x2ZShyZXBvcnQpKVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TG9jYWxJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5sb2NhbENhbmRpZGF0ZXNRdWV1ZTtcbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJTZW5kKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IHVzZXJNZWRpYUNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaXNTZW5kVmlkZW8oKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbTogdGhpcy5tZWRpYVN0cmVhbSxcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB1c2VyTWVkaWFDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IGZhbHNlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBzdWNjZXNzQ2FsbGJhY2sgPSAoc2RwT2ZmZXJQYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1NlbmRpbmcgU0RQIG9mZmVyIHRvIHB1Ymxpc2ggYXMgJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuXG4gICAgICAgICAgICAgICAgbGV0IHR5cGVPZlZpZGVvID0gJyc7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICB0eXBlT2ZWaWRlbyA9ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gJ0NVU1RPTScgOiAodGhpcy5pc1NlbmRTY3JlZW4oKSA/ICdTQ1JFRU4nIDogJ0NBTUVSQScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncHVibGlzaFZpZGVvJywge1xuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbSxcbiAgICAgICAgICAgICAgICAgICAgZG9Mb29wYmFjazogdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgaGFzQXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICAgICAgaGFzVmlkZW86IHRoaXMuaXNTZW5kVmlkZW8oKSxcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHRoaXMuYXVkaW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiB0aGlzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlT2ZWaWRlbyxcbiAgICAgICAgICAgICAgICAgICAgZnJhbWVSYXRlOiAhIXRoaXMuZnJhbWVSYXRlID8gdGhpcy5mcmFtZVJhdGUgOiAtMSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiBKU09OLnN0cmluZ2lmeSh0aGlzLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcjogdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5maWx0ZXJcbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBwdWJsaXNoXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdFcnJvciBvbiBwdWJsaXNoVmlkZW86ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSByZXNwb25zZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSByZXNwb25zZS5jcmVhdGVkQXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCInUHVibGlzaGVyJyBzdWNjZXNzZnVsbHkgcHVibGlzaGVkIHRvIHNlc3Npb25cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJTZW5kcmVjdihvcHRpb25zKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJTZW5kb25seShvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5nZW5lcmF0ZU9mZmVyKCkudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCcocHVibGlzaCkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclJlY2VpdmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgb2ZmZXJDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNBdWRpbyxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNWaWRlb1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoXCInU2Vzc2lvbi5zdWJzY3JpYmUoU3RyZWFtKScgY2FsbGVkLiBDb25zdHJhaW50cyBvZiBnZW5lcmF0ZSBTRFAgb2ZmZXJcIixcbiAgICAgICAgICAgICAgICBvZmZlckNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiBvZmZlckNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IGZhbHNlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBzdWNjZXNzQ2FsbGJhY2sgPSAoc2RwT2ZmZXJQYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1NlbmRpbmcgU0RQIG9mZmVyIHRvIHN1YnNjcmliZSB0byAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdyZWNlaXZlVmlkZW9Gcm9tJywge1xuICAgICAgICAgICAgICAgICAgICBzZW5kZXI6IHRoaXMuc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIG9uIHJlY3ZWaWRlb0Zyb206ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElvcyBJb25pYy4gTGltaXRhdGlvbjogc29tZSBidWcgaW4gaW9zcnRjIGNvcmRvdmEgcGx1Z2luIG1ha2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBuZWNlc3NhcnkgdG8gYWRkIGEgdGltZW91dCBiZWZvcmUgcHJvY2Vzc0Fuc3dlciBtZXRob2RcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uWydpb3NJbnRlcnZhbCddID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fzd2VyID0gdGhpcy5zZXNzaW9uLmNvdW50RG93bkZvcklvbmljSW9zU3Vic2NyaWJlcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fzd2VyKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJSZWN2b25seShvcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5nZW5lcmF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTogdm9pZCB7XG4gICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLndlYlJ0Y1BlZXIucGM7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gcGMxLmdldFJlbW90ZVN0cmVhbXMoKVswXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIGxldCByZWNlaXZlcjogUlRDUnRwUmVjZWl2ZXI7XG4gICAgICAgICAgICBmb3IgKHJlY2VpdmVyIG9mIHRoaXMud2ViUnRjUGVlci5wYy5nZXRSZWNlaXZlcnMoKSkge1xuICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uYWRkVHJhY2socmVjZWl2ZXIudHJhY2spO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmRlYnVnKCdQZWVyIHJlbW90ZSBzdHJlYW0nLCB0aGlzLm1lZGlhU3RyZWFtKTtcblxuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtKSB7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbU1hbmFnZXIgaW5zdGFuY2VvZiBTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgU3Vic2NyaWJlclByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyBhbmQgU3Vic2NyaWJlclByb3BlcnRpZXMuc3Vic2NyaWJlVG9WaWRlb1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9WaWRlbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3BsYXlNeVJlbW90ZSgpICYmICEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdICYmIHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy53ZWJSdGNTdGF0cyA9IG5ldyBXZWJSdGNTdGF0cyh0aGlzKTtcbiAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5pbml0V2ViUnRjU3RhdHMoKTtcblxuICAgICAgICAvL1RPRE86IHNlbmQgY29tbW9uIHdlYnJ0YyBzdGF0cyBmcm9tIGNsaWVudCB0byBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgLyppZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgPiAwKSB7XG4gICAgICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5nYXRoZXJTdGF0c0ZvclBlZXIoKS50aGVuKGpzb25TdGF0cyA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvZHkgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudFByaXZhdGVJZDogdGhpcy5jb25uZWN0aW9uLnJwY1Nlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzOiBqc29uU3RhdHNcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5vcGVuKCdQT1NUJywgdGhpcy5zZXNzaW9uLm9wZW52aWR1Lmh0dHBVcmkgKyAnL2VsYXN0aWNzZWFyY2gvd2VicnRjLXN0YXRzJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2VuZChKU09OLnN0cmluZ2lmeShib2R5KSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0sIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsICogMTAwMCk7XG4gICAgICAgIH0qL1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1N0YXRzICYmIHRoaXMud2ViUnRjU3RhdHMuaXNFbmFibGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEljZVNlcnZlcnNDb25mKCk6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgbGV0IHJldHVyblZhbHVlO1xuICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID09PSAnZnJlZWljZScgP1xuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5pY2VTZXJ2ZXJzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2F0aGVyU3RhdHNGb3JQZWVyKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsKCkpIHtcblxuICAgICAgICAgICAgICAgIC8vIFB1Ymxpc2hlciBzdHJlYW0gc3RhdHNcblxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTZW5kZXJzKCkuZm9yRWFjaChzZW5kZXIgPT4gc2VuZGVyLmdldFN0YXRzKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZm9yRWFjaChyZXBvcnQgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVwb3J0V2FudGVkKHJlcG9ydCkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmluYWxSZXBvcnQgPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3R5cGUnXSA9IHJlcG9ydC50eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3RpbWVzdGFtcCddID0gcmVwb3J0LnRpbWVzdGFtcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydpZCddID0gcmVwb3J0LmlkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21tb24gdG8gQ2hyb21lLCBGaXJlZm94IGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNFbmNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1NlbnQnXSA9IHJlcG9ydC5wYWNrZXRzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYnl0ZXNTZW50J10gPSByZXBvcnQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZU91dGdvaW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZU91dGdvaW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZmluYWxSZXBvcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgLy8gU3Vic2NyaWJlciBzdHJlYW0gc3RhdHNcblxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRSZWNlaXZlcnMoKS5mb3JFYWNoKHJlY2VpdmVyID0+IHJlY2VpdmVyLmdldFN0YXRzKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZm9yRWFjaChyZXBvcnQgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVwb3J0V2FudGVkKHJlcG9ydCkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmluYWxSZXBvcnQgPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3R5cGUnXSA9IHJlcG9ydC50eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3RpbWVzdGFtcCddID0gcmVwb3J0LnRpbWVzdGFtcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydpZCddID0gcmVwb3J0LmlkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21tb24gdG8gQ2hyb21lLCBGaXJlZm94IGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0RlY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzUmVjZWl2ZWQnXSA9IHJlcG9ydC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNMb3N0J10gPSByZXBvcnQucGFja2V0c0xvc3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ppdHRlciddID0gcmVwb3J0LmppdHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYnl0ZXNSZWNlaXZlZCddID0gcmVwb3J0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlSW5jb21pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlSW5jb21pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZmluYWxSZXBvcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUmVwb3J0V2FudGVkKHJlcG9ydDogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiByZXBvcnQudHlwZSA9PT0gJ2luYm91bmQtcnRwJyAmJiAhdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJyAmJiB0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC5ub21pbmF0ZWQgJiYgcmVwb3J0LmJ5dGVzU2VudCA+IDApO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlclZpZGVvIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdHJlYW1NYW5hZ2VyVmlkZW8nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1NYW5hZ2VyRXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9FbGVtZW50RXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9WaWRlb0VsZW1lbnRFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBJbnRlcmZhY2UgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhlIG1lZGlhIHN0cmVhbXMgaW4gdGhlIEhUTUwgRE9NLiBUaGlzIHdyYXBzIGFueSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSBvYmplY3QuXG4gKiBZb3UgY2FuIGluc2VydCBhcyBtYW55IHZpZGVvIHBsYXllcnMgZm8gdGhlIHNhbWUgU3RyZWFtIGFzIHlvdSB3YW50IGJ5IGNhbGxpbmcgW1tTdHJlYW1NYW5hZ2VyLmFkZFZpZGVvRWxlbWVudF1dIG9yXG4gKiBbW1N0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0uXG4gKlxuICogVGhlIHVzZSBvZiBTdHJlYW1NYW5hZ2VyIHdyYXBwZXIgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHlvdSBkb24ndCBuZWVkIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBQdWJsaXNoZXIgb3IgU3Vic2NyaWJlciBzdHJlYW1zIG9yIGp1c3RcbiAqIHdhbnQgdG8gZGlyZWN0bHkgbWFuYWdlIHlvdXIgb3duIHZpZGVvIGVsZW1lbnRzIChldmVuIG1vcmUgdGhhbiBvbmUgdmlkZW8gZWxlbWVudCBwZXIgU3RyZWFtKS4gVGhpcyBzY2VuYXJpbyBpcyBwcmV0dHkgY29tbW9uIGluXG4gKiBkZWNsYXJhdGl2ZSwgTVZDIGZyb250ZW5kIGZyYW1ld29ya3Mgc3VjaCBhcyBBbmd1bGFyLCBSZWFjdCBvciBWdWUuanNcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbU1hbmFnZXIgaW1wbGVtZW50cyBFdmVudERpc3BhdGNoZXIge1xuXG4gICAgLyoqXG4gICAgICogVGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGJ5IHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogQWxsIHRoZSB2aWRlb3MgZGlzcGxheWluZyB0aGUgU3RyZWFtIG9mIHRoaXMgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICB2aWRlb3M6IFN0cmVhbU1hbmFnZXJWaWRlb1tdID0gW107XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBpcyBsb2NhbCBvciByZW1vdGVcbiAgICAgKiAtIGBmYWxzZWAgZm9yIFtbUHVibGlzaGVyXV1cbiAgICAgKiAtIGB0cnVlYCBmb3IgW1tTdWJzY3JpYmVyXV1cbiAgICAgKi9cbiAgICByZW1vdGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgRE9NIEhUTUxFbGVtZW50IGFzc2lnbmVkIGFzIHRhcmdldCBlbGVtZW50IHdoZW4gY3JlYXRpbmcgdGhlIHZpZGVvIGZvciB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIuIFRoaXMgcHJvcGVydHkgaXMgb25seSBkZWZpbmVkIGlmOlxuICAgICAqIC0gW1tQdWJsaXNoZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqIC0gW1tTdWJzY3JpYmVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICovXG4gICAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBgaWRgIGF0dHJpYnV0ZSBvZiB0aGUgRE9NIHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIncyBzdHJlYW0uIFRoaXMgcHJvcGVydHkgaXMgb25seSBkZWZpbmVkIGlmOlxuICAgICAqIC0gW1tQdWJsaXNoZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqIC0gW1tTdWJzY3JpYmVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICovXG4gICAgaWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBmaXJzdFZpZGVvRWxlbWVudDogU3RyZWFtTWFuYWdlclZpZGVvO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNhblBsYXlMaXN0ZW5lcjogRXZlbnRMaXN0ZW5lcjtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50PzogSFRNTEVsZW1lbnQgfCBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIgPSB0aGlzO1xuICAgICAgICB0aGlzLnJlbW90ZSA9ICF0aGlzLnN0cmVhbS5pc0xvY2FsKCk7XG5cbiAgICAgICAgaWYgKCEhdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCEhdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKSxcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICcnLFxuICAgICAgICAgICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldEVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYW5QbGF5TGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIGxvY2FsICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBvd24gcmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJSZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1wiICsgKHRoaXMucmVtb3RlID8gJ1N1YnNjcmliZXInIDogJ1B1Ymxpc2hlcicpICsgXCInXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1wiICsgKHRoaXMucmVtb3RlID8gJ1N1YnNjcmliZXInIDogJ1B1Ymxpc2hlcicpICsgXCInXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vZmZdXVxuICAgICAqL1xuICAgIG9mZih0eXBlOiBzdHJpbmcsIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5lZS5yZW1vdmVBbGxMaXN0ZW5lcnModHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmVlLm9mZih0eXBlLCBoYW5kbGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGB2aWRlb2AgZWxlbWVudCBwYXJhbWV0ZXIgZGlzcGxheSB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgaXMgdXNlZnVsIHdoZW4geW91IGFyZVxuICAgICAqIFttYW5hZ2luZyB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd25dKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI3lvdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpXG4gICAgICpcbiAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIHdpdGggYSB2aWRlbyBhbHJlYWR5IGFkZGVkIHRvIG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgY2F1c2UgdGhlIHZpZGVvIGVsZW1lbnQgdG8gYmVcbiAgICAgKiBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBwcmV2aW91cyBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgdG8gYmUgYXNzb2NpYXRlZCB0byB0aGlzIG9uZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIDEgaWYgdGhlIHZpZGVvIHdhc24ndCBhc3NvY2lhdGVkIHRvIGFueSBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqIDAgaWYgdGhlIHZpZGVvIHdhcyBhbHJlYWR5IGFkZGVkIHRvIHRoaXMgUHVibGlzaGVyL1N1YnNjcmliZXIuIC0xIGlmIHRoZSB2aWRlbyB3YXMgcHJldmlvdXNseSBhc3NvY2lhdGVkIHRvIGFueSBvdGhlclxuICAgICAqIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgb25lIGFuZCBwcm9wZXJseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKi9cbiAgICBhZGRWaWRlb0VsZW1lbnQodmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiBudW1iZXIge1xuXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgaWYgKHZpZGVvLnNyY09iamVjdCAhPT0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKSkge1xuICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgdmlkZW8gZWxlbWVudCBpcyBhbHJlYWR5IHBhcnQgb2YgdGhpcyBTdHJlYW1NYW5hZ2VyIGRvIG5vdGhpbmdcbiAgICAgICAgZm9yIChjb25zdCB2IG9mIHRoaXMudmlkZW9zKSB7XG4gICAgICAgICAgICBpZiAodi52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXR1cm5OdW1iZXIgPSAxO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RyZWFtTWFuYWdlciBvZiB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzKSB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5OdW1iZXIgPSAtMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuZm9yRWFjaChzdHJlYW1NYW5hZ2VyID0+IHtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oe1xuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCdOZXcgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvICcsIHRoaXMpO1xuXG4gICAgICAgIHJldHVybiByZXR1cm5OdW1iZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGFsbG93cyB5b3UgdG8gaGF2ZSBtdWx0aXBsZSB2aWRlbyBlbGVtZW50cyBkaXNwbGF5aW5nIHRoZSBzYW1lIG1lZGlhIHN0cmVhbS5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGJlIGluc2VydGVkXG4gICAgICogQHBhcmFtIGluc2VydE1vZGUgSG93IHRoZSB2aWRlbyBlbGVtZW50IHdpbGwgYmUgaW5zZXJ0ZWQgYWNjb3JkaW5nbHkgdG8gYHRhcmdldEVsZW1ldGBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIEhUTUxWaWRlb0VsZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVWaWRlb0VsZW1lbnQodGFyZ2V0RWxlbWVudD86IHN0cmluZyB8IEhUTUxFbGVtZW50LCBpbnNlcnRNb2RlPzogVmlkZW9JbnNlcnRNb2RlKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKCF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGxldCBpbnNNb2RlID0gISFpbnNlcnRNb2RlID8gaW5zZXJ0TW9kZSA6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ7XG4gICAgICAgIHN3aXRjaCAoaW5zTW9kZSkge1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQUZURVI6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5uZXh0U2libGluZyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmFwcGVuZENoaWxkKHZpZGVvKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkJFRk9SRTpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlBSRVBFTkQ6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUkVQTEFDRTpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLnJlcGxhY2VDaGlsZCh2aWRlbywgdGFyZ0VsKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5zTW9kZSA9IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ7XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmFwcGVuZENoaWxkKHZpZGVvKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHY6IFN0cmVhbU1hbmFnZXJWaWRlbyA9IHtcbiAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaW5zZXJ0TW9kZTogaW5zTW9kZSxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8odik7XG5cbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHYudmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gISF0aGlzLmZpcnN0VmlkZW9FbGVtZW50O1xuXG4gICAgICAgIHJldHVybiB2aWRlbztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBpZiAoISh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpKSB7XG4gICAgICAgICAgICAvLyBBdm9pZCBzZXR0aW5nIHRoZSBNZWRpYVN0cmVhbSBpbnRvIHRoZSBzcmNPYmplY3QgaWYgcmVtb3RlIHN1YnNjcmlwdGlvbiBiZWZvcmUgcHVibGlzaGluZ1xuICAgICAgICAgICAgaWYgKHZpZGVvLnNyY09iamVjdCAhPT0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKSkge1xuICAgICAgICAgICAgICAgIC8vIElmIHNyY09iamVjdCBhbHJlYWR5IHNldCBkb24ndCBkbyBpdCBhZ2FpblxuICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmlkZW8uYXV0b3BsYXkgPSB0cnVlO1xuICAgICAgICB2aWRlby5jb250cm9scyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXZpZGVvLmlkKSB7XG4gICAgICAgICAgICB2aWRlby5pZCA9ICh0aGlzLnJlbW90ZSA/ICdyZW1vdGUtJyA6ICdsb2NhbC0nKSArICd2aWRlby0nICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQ7XG4gICAgICAgICAgICAvLyBERVBSRUNBVEVEIHByb3BlcnR5OiBhc3NpZ24gb25jZSB0aGUgcHJvcGVydHkgaWQgaWYgdGhlIHVzZXIgcHJvdmlkZWQgYSB2YWxpZCB0YXJnZXRFbGVtZW50XHRcbiAgICAgICAgICAgIGlmICghdGhpcy5pZCAmJiAhIXRoaXMudGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaWQgPSB2aWRlby5pZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5yZW1vdGUgJiYgIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICB2aWRlby5tdXRlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3R5bGUudHJhbnNmb3JtID09PSAncm90YXRlWSgxODBkZWcpJyAmJiAhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZpZGVvIHdhcyBhbHJlYWR5IHJvdGF0ZWQgYW5kIG5vdyBpcyBzZXQgdG8gbm90IG1pcnJvclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IgJiYgIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5taXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3ZlQWxsVmlkZW9zKCk6IHZvaWQge1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnNbaV0gPT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmlkZW9zLmZvckVhY2goc3RyZWFtTWFuYWdlclZpZGVvID0+IHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBvbmNhbnBsYXkgZXZlbnQgbGlzdGVuZXIgKG9ubHkgT3BlblZpZHUgYnJvd3NlciBsaXN0ZW5lciwgbm90IHRoZSB1c2VyIG9uZXMpXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby5jYW5wbGF5TGlzdGVuZXJBZGRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKCEhc3RyZWFtTWFuYWdlclZpZGVvLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IHJlbW92ZSBmcm9tIERPTSB2aWRlb3MgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyICh0aG9zZSBnZW5lcmF0ZWQgYnkgcGFzc2luZyBhIHZhbGlkIHRhcmdldEVsZW1lbnQgaW4gT3BlblZpZHUuaW5pdFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIC8vIGFuZCBTZXNzaW9uLnN1YnNjcmliZSBvciB0aG9zZSBjcmVhdGVkIGJ5IFN0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50KS4gQWxsIHRoaXMgdmlkZW9zIHRyaWdnZXJlZCBhIHZpZGVvRWxlbWVudENyZWF0ZWQgZXZlbnRcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8ucGFyZW50Tm9kZSEucmVtb3ZlQ2hpbGQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50RGVzdHJveWVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnREZXN0cm95ZWQnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVtb3ZlIHNyY09iamVjdCBmcm9tIHRoZSB2aWRlb1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBjb2xsZWN0aW9uIG9mIHZpZGVvcyBldmVyeSB2aWRlbyBtYW5hZ2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICAgICAgICAgIHRoaXMudmlkZW9zLmZpbHRlcih2ID0+ICF2LnRhcmdldEVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYXNzb2NpYXRlVmlkZW8odmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGRpc2Fzc29jaWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZpZGVvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zW2ldLnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zW2ldLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgIGRpc2Fzc29jaWF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVmlkZW8gZWxlbWVudCBkaXNhc3NvY2lhdGVkIGZyb20gJywgdGhpcyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpc2Fzc29jaWF0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpIHtcbiAgICAgICAgaWYgKCghIXRoaXMudmlkZW9zWzBdKSAmJiAoISF0aGlzLnZpZGVvc1swXS52aWRlbykgJiYgKCF0aGlzLnZpZGVvc1swXS5jYW5wbGF5TGlzdGVuZXJBZGRlZCkpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS5jYW5wbGF5TGlzdGVuZXJBZGRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKSB7XG4gICAgICAgIHRoaXMudmlkZW9zLmZvckVhY2goc3RyZWFtTWFuYWdlclZpZGVvID0+IHtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbTtcbiAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHJlaW5zZXJ0IHRoZSB2aWRlbyBpbiB0aGUgRE9NIGZvclxuICAgICAgICAgICAgICAgIC8vIHRoZSBtZWRpYSBzdHJlYW0gdG8gYmUgdXBkYXRlZFxuICAgICAgICAgICAgICAgIGNvbnN0IHZQYXJlbnQgPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8ucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdWaWRlbyA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbztcbiAgICAgICAgICAgICAgICB2UGFyZW50ISEucmVwbGFjZUNoaWxkKG5ld1ZpZGVvLCBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyA9IG5ld1ZpZGVvO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHN0cmVhbU1hbmFnZXJWaWRlbzogU3RyZWFtTWFuYWdlclZpZGVvKSB7XG4gICAgICAgIHRoaXMudmlkZW9zLnB1c2goc3RyZWFtTWFuYWdlclZpZGVvKTtcbiAgICAgICAgdGhpcy5hZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKTtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuaW5kZXhPZih0aGlzKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMucHVzaCh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgaWYgKCFwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS50cmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICB2aWRlby5zdHlsZS50cmFuc2Zvcm0gPSAndW5zZXQnO1xuICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAndW5zZXQnO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuXG5cbi8qKlxuICogUGFja3MgcmVtb3RlIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBhdXRvbWF0aWNhbGx5IHJlY2VpdmUgdGhlbSB3aGVuIG90aGVycyBwdWJsaXNoIHRoZWlyIHN0cmVhbXMuIEluaXRpYWxpemVkIHdpdGggW1tTZXNzaW9uLnN1YnNjcmliZV1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU3Vic2NyaWJlciBleHRlbmRzIFN0cmVhbU1hbmFnZXIge1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbTogU3RyZWFtLCB0YXJnRWw6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcykge1xuICAgICAgICBzdXBlcihzdHJlYW0sIHRhcmdFbCk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IHRoaXMudGFyZ2V0RWxlbWVudDtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIG9yIHVuc3Vic2NyaWJlIGZyb20gdGhlIGF1ZGlvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgdmFsdWUgd2lsbCBoYXZlIG5vIGVmZmVjdFxuICAgICAqIEBwYXJhbSB2YWx1ZSBgdHJ1ZWAgdG8gc3Vic2NyaWJlIHRvIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5zdWJzY3JpYmUgZnJvbSBpdFxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvQXVkaW8odmFsdWU6IGJvb2xlYW4pOiBTdWJzY3JpYmVyIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmluZm8oXCInU3Vic2NyaWJlcicgaGFzIFwiICsgKHZhbHVlID8gJ3N1YnNjcmliZWQgdG8nIDogJ3Vuc3Vic2NyaWJlZCBmcm9tJykgKyAnIGl0cyBhdWRpbyBzdHJlYW0nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIG9yIHVuc3Vic2NyaWJlIGZyb20gdGhlIHZpZGVvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgdmFsdWUgd2lsbCBoYXZlIG5vIGVmZmVjdFxuICAgICAqIEBwYXJhbSB2YWx1ZSBgdHJ1ZWAgdG8gc3Vic2NyaWJlIHRvIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5zdWJzY3JpYmUgZnJvbSBpdFxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvVmlkZW8odmFsdWU6IGJvb2xlYW4pOiBTdWJzY3JpYmVyIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmluZm8oXCInU3Vic2NyaWJlcicgaGFzIFwiICsgKHZhbHVlID8gJ3N1YnNjcmliZWQgdG8nIDogJ3Vuc3Vic2NyaWJlZCBmcm9tJykgKyAnIGl0cyB2aWRlbyBzdHJlYW0nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5leHBvcnQgZW51bSBMb2NhbFJlY29yZGVyU3RhdGUge1xuICAgIFJFQURZID0gJ1JFQURZJyxcbiAgICBSRUNPUkRJTkcgPSAnUkVDT1JESU5HJyxcbiAgICBQQVVTRUQgPSAnUEFVU0VEJyxcbiAgICBGSU5JU0hFRCA9ICdGSU5JU0hFRCdcbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogRGVmaW5lcyBwcm9wZXJ0eSBbW09wZW5WaWR1RXJyb3IubmFtZV1dXG4gKi9cbmV4cG9ydCBlbnVtIE9wZW5WaWR1RXJyb3JOYW1lIHtcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgaXMgbm90IHN1cHBvcnRlZCBieSBPcGVuVmlkdS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW1Nlc3Npb24uY29ubmVjdF1dXG4gICAgICovXG4gICAgQlJPV1NFUl9OT1RfU1VQUE9SVEVEID0gJ0JST1dTRVJfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdXNlciBoYXNuJ3QgZ3JhbnRlZCBwZXJtaXNzaW9ucyB0byB0aGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIERFVklDRV9BQ0NFU1NfREVOSUVEID0gJ0RFVklDRV9BQ0NFU1NfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2UgaXMgcHJvYmFibHkgYmVpbmcgdXNlZCBieSBvdGhlciBwcm9jZXNzIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIGl0LlxuICAgICAqIEFjY3VyYWN5IG9mIHRoaXMgcHJvcGVydHkgaXMgb25seSBncmFudGVkIGZvciBDaHJvbWUgYW5kIEZpcmVmb3ggY2xpZW50cy4gXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIERFVklDRV9BTFJFQURZX0lOX1VTRSA9IFwiREVWSUNFX0FMUkVBRFlfSU5fVVNFXCIsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdXNlciBoYXNuJ3QgZ3JhbnRlZCBwZXJtaXNzaW9ucyB0byBjYXB0dXJlIHNvbWUgZGVza3RvcCBzY3JlZW4gd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgU0NSRUVOX0NBUFRVUkVfREVOSUVEID0gJ1NDUkVFTl9DQVBUVVJFX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGRvZXMgbm90IHN1cHBvcnQgc2NyZWVuIHNoYXJpbmcuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEID0gJ1NDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogT25seSBmb3IgQ2hyb21lLCB0aGVyZSdzIG5vIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpbnN0YWxsZWRcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQnLFxuXG4gICAgLyoqXG4gICAgICogT25seSBmb3IgQ2hyb21lLCB0aGUgc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCBidXQgaXMgZGlzYWJsZWRcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCcsXG5cbiAgICAvKipcbiAgICAgKiBObyB2aWRlbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE5vIGF1ZGlvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIGhhcyBiZWVuIGNhbGxlZCB3aXRoIHByb3BlcnRpZXMgYHZpZGVvU291cmNlYCBhbmQgYGF1ZGlvU291cmNlYCBvZlxuICAgICAqIFtbUHVibGlzaGVyUHJvcGVydGllc11dIHBhcmFtZXRlciBib3RoIHNldCB0byAqZmFsc2UqIG9yICpudWxsKlxuICAgICAqL1xuICAgIE5PX0lOUFVUX1NPVVJDRV9TRVQgPSAnTk9fSU5QVVRfU09VUkNFX1NFVCcsXG5cbiAgICAvKipcbiAgICAgKiBTb21lIG1lZGlhIHByb3BlcnR5IG9mIFtbUHVibGlzaGVyUHJvcGVydGllc11dIHN1Y2ggYXMgYGZyYW1lUmF0ZWAgb3IgYHJlc29sdXRpb25gIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgKiBieSB0aGUgaW5wdXQgZGV2aWNlcyAod2hlbmV2ZXIgaXQgaXMgcG9zc2libGUgdGhleSBhcmUgYXV0b21hdGljYWxseSBhZGp1c3RlZCB0byB0aGUgbW9zdCBzaW1pbGFyIHZhbHVlKS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SID0gJ1BVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdHJpZWQgdG8gY2FsbCBhIG1ldGhvZCB3aXRob3V0IHRoZSByZXF1aXJlZCBwZXJtaXNzaW9ucy4gVGhpcyBjYW4gb2NjdXIgZm9yIG1ldGhvZHMgW1tTZXNzaW9uLnB1Ymxpc2hdXSxcbiAgICAgKiBbW1Nlc3Npb24uZm9yY2VVbnB1Ymxpc2hdXSwgW1tTZXNzaW9uLmZvcmNlRGlzY29ubmVjdF1dLCBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBbW1N0cmVhbS5yZW1vdmVGaWx0ZXJdXVxuICAgICAqL1xuICAgIE9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEID0gJ09QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBPUEVOVklEVV9OT1RfQ09OTkVDVEVEID0gJ09QRU5WSURVX05PVF9DT05ORUNURUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIEdFTkVSSUNfRVJST1IgPSAnR0VORVJJQ19FUlJPUidcbn1cblxuLyoqXG4gKiBTaW1wbGUgb2JqZWN0IHRvIGlkZW50aWZ5IHJ1bnRpbWUgZXJyb3JzIG9uIHRoZSBjbGllbnQgc2lkZVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHVFcnJvciB7XG5cbiAgICBuYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobmFtZTogT3BlblZpZHVFcnJvck5hbWUsIG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBIb3cgdGhlIHZpZGVvIHdpbGwgYmUgaW5zZXJ0ZWQgaW4gdGhlIERPTSBmb3IgUHVibGlzaGVycyBhbmQgU3Vic2NyaWJlcnMuIFNlZSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dIGFuZCBbW1N1YnNjcmliZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXVxuICovXG5leHBvcnQgZW51bSBWaWRlb0luc2VydE1vZGUge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYWZ0ZXIgdGhlIHRhcmdldCBlbGVtZW50IChhcyBuZXh0IHNpYmxpbmcpXG4gICAgICovXG4gICAgQUZURVIgPSAnQUZURVInLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGxhc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgQVBQRU5EID0gJ0FQUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYmVmb3JlIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgcHJldmlvdXMgc2libGluZylcbiAgICAgKi9cbiAgICBCRUZPUkUgPSAnQkVGT1JFJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBmaXJzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBQUkVQRU5EID0gJ1BSRVBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIHJlcGxhY2VzIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUkVQTEFDRSA9ICdSRVBMQUNFJ1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYGNvbm5lY3Rpb25DcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgY29ubmVjdGlvbkRlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIENvbm5lY3Rpb24gb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEZvciBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQ6XG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKlxuICAgICAqIEZvciBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50IGFuIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihjYW5jZWxhYmxlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGV2ZW50IGhhcyBhIGRlZmF1bHQgYmVoYXZpb3IgdGhhdCBtYXkgYmUgcHJldmVudGVkIGJ5IGNhbGxpbmcgW1tFdmVudC5wcmV2ZW50RGVmYXVsdF1dXG4gICAgICovXG4gICAgY2FuY2VsYWJsZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBldmVudC4gVGhpcyBpcyB0aGUgc2FtZSBzdHJpbmcgeW91IHBhc3MgYXMgZmlyc3QgcGFyYW1ldGVyIHdoZW4gY2FsbGluZyBtZXRob2QgYG9uKClgIG9mIGFueSBvYmplY3QgaW1wbGVtZW50aW5nIFtbRXZlbnREaXNwYXRjaGVyXV0gaW50ZXJmYWNlXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhc0JlZW5QcmV2ZW50ZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZTtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZGVmYXVsdCBiZWFoaXZvdXIgb2YgdGhlIGV2ZW50IGhhcyBiZWVuIHByZXZlbnRlZCBvciBub3QuIENhbGwgW1tFdmVudC5wcmV2ZW50RGVmYXVsdF1dIHRvIHByZXZlbnQgaXRcbiAgICAgKi9cbiAgICBpc0RlZmF1bHRQcmV2ZW50ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc0JlZW5QcmV2ZW50ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIGV2ZW50LiBUaGUgZm9sbG93aW5nIGV2ZW50cyBoYXZlIGEgZGVmYXVsdCBiZWhhdmlvcjpcbiAgICAgKlxuICAgICAqIC0gYHNlc3Npb25EaXNjb25uZWN0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIG9iamVjdCwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIGxlYXZpbmcgcGFydGljaXBhbnQgZnJvbSBldmVyeSBTdWJzY3JpYmVyIG9iamVjdCBvZiB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gZWFjaCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCBlYWNoIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogLSBgc3RyZWFtRGVzdHJveWVkYDpcbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBhIFtbUHVibGlzaGVyXV0gKCp5b3UqIGhhdmUgdW5wdWJsaXNoZWQpOiBhdXRvbWF0aWNhbGx5IHN0b3BzIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgXG4gICAgICogaW4gbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIGJ5IGNhbGxpbmcgW1tQdWJsaXNoZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFB1Ymxpc2hlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gKCpvdGhlciB1c2VyKiBoYXMgdW5wdWJsaXNoZWQpOiBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgcHJvcGVyIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqL1xuICAgIHByZXZlbnREZWZhdWx0KCkge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICAgICAgdGhpcy5jYWxsRGVmYXVsdEJlaGF2aW9yID0gKCkgPT4geyB9O1xuICAgICAgICB0aGlzLmhhc0JlZW5QcmV2ZW50ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhYnN0cmFjdCBjYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlcnkgZXZlbnQgZGlzcGF0Y2hlZCBieSBhdWRpby92aWRlbyBzdHJlYW0gZmlsdGVycy4gWW91IGNhbiBzdWJzY3JpYmUgdG8gZmlsdGVyIGV2ZW50cyBieSBjYWxsaW5nIFtbRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXJdXVxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBEYXRhIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIGRhdGE6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IEZpbHRlciwgZXZlbnRUeXBlOiBzdHJpbmcsIGRhdGE6IE9iamVjdCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCBldmVudFR5cGUpO1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKlxuICogTW9yZSBpbmZvcm1hdGlvbjpcbiAqIC0gVGhpcyBldmVudHMgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBmb3IgKipyZW1vdGUgc3RyZWFtcyB0aGF0IGhhdmUgYXVkaW8gdHJhY2tzKiogKFtbU3RyZWFtLmhhc0F1ZGlvXV0gbXVzdCBiZSB0cnVlKVxuICogLSBCb3RoIGV2ZW50cyBzaGFyZSB0aGUgc2FtZSBsaWZlY3ljbGUuIFRoYXQgbWVhbnMgdGhhdCB5b3UgY2FuIHN1YnNjcmliZSB0byBvbmx5IG9uZSBvZiB0aGVtIGlmIHlvdSB3YW50LCBidXQgaWYgeW91IGNhbGwgYFNlc3Npb24ub2ZmKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKWAsXG4gKiBrZWVwIGluIG1pbmQgdGhhdCB0aGlzIHdpbGwgYWxzbyBpbnRlcm5hbGx5IHJlbW92ZSBhbnkgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGV2ZW50XG4gKiAtIFlvdSBjYW4gZnVydGhlciBjb25maWd1cmUgaG93IHRoZSBldmVudHMgYXJlIGRpc3BhdGNoZWQgYnkgc2V0dGluZyBwcm9wZXJ0eSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYCBpbiB0aGUgY2FsbCBvZiBbW09wZW5WaWR1LnNldEFkdmFuY2VkQ29uZmlndXJhdGlvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHN0YXJ0ZWQgb3Igc3RvcHBlZCBzcGVha2luZ1xuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3RyZWFtSWQgb2YgdGhlIFN0cmVhbSBhZmZlY3RlZCBieSB0aGUgc3BlYWtpbmcgZXZlbnRcbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCBzdHJlYW1JZDogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLnN0cmVhbUlkID0gc3RyZWFtSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGByZWNvcmRpbmdTdGFydGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcmVjb3JkaW5nU3RvcHBlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFJlY29yZGluZ0V2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBJRCBnZW5lcmF0ZWQgaW4gb3BlbnZpZHUtc2VydmVyXG4gICAgICovXG4gICAgaWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgbmFtZSB5b3Ugc3VwcGxpZWQgdG8gb3BlbnZpZHUtc2VydmVyLiBGb3IgZXhhbXBsZSwgdG8gbmFtZSB5b3VyIHJlY29yZGluZyBmaWxlIE1ZX1JFQ09SRElORzpcbiAgICAgKiAtIFdpdGggKipBUEkgUkVTVCoqOiBQT1NUIHRvIGAvYXBpL3JlY29yZGluZ3Mvc3RhcnRgIHBhc3NpbmcgSlNPTiBib2R5IGB7XCJzZXNzaW9uXCI6XCJzZXNzaW9uSWRcIixcIm5hbWVcIjpcIk1ZX1JFQ09SRElOR1wifWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1qYXZhLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgbmV3IFJlY29yZGluZ1Byb3BlcnRpZXMuQnVpbGRlcigpLm5hbWUoXCJNWV9SRUNPUkRJTkdcIikuYnVpbGQoKSlgXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtbm9kZS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIHtuYW1lOiBcIk1ZX1JFQ09SRElOR1wifSlgXG4gICAgICpcbiAgICAgKiBJZiBubyBuYW1lIGlzIHN1cHBsaWVkLCB0aGlzIHByb3BlcnR5IHdpbGwgYmUgdW5kZWZpbmVkIGFuZCB0aGUgcmVjb3JkZWQgZmlsZSB3aWxsIGJlIG5hbWVkIGFmdGVyIHByb3BlcnR5IFtbaWRdXVxuICAgICAqL1xuICAgIG5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0b3BwZWQnIGV2ZW50OlxuICAgICAqIC0gXCJyZWNvcmRpbmdTdG9wcGVkQnlTZXJ2ZXJcIjogdGhlIHJlY29yZGluZyBoYXMgYmVlbiBncmFjZWZ1bGx5IHN0b3BwZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImF1dG9tYXRpY1N0b3BcIjogc2VlIFtBdXRvbWF0aWMgc3RvcCBvZiByZWNvcmRpbmdzXShodHRwczovL29wZW52aWR1LmlvL2RvY3MvYWR2YW5jZWQtZmVhdHVyZXMvcmVjb3JkaW5nLyNhdXRvbWF0aWMtc3RvcC1vZi1yZWNvcmRpbmdzKVxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gc3RvcHBlZCAobm8gbWVkaWEgc3RyZWFtcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBuZXcgbWVkaWEgc2VydmVyKVxuICAgICAqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdGFydGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb24/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGlkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgcmVhc29uPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIGlmIChuYW1lICE9PSBpZCkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVudCBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogeW91IGhhdmUgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHlvdXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcih0cnVlLCB0YXJnZXQsICdzZXNzaW9uRGlzY29ubmVjdGVkJyk7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcblxuICAgICAgICBjb25zdCBzZXNzaW9uID0gPFNlc3Npb24+dGhpcy50YXJnZXQ7XG5cbiAgICAgICAgLy8gRGlzcG9zZSBhbmQgZGVsZXRlIGFsbCByZW1vdGUgQ29ubmVjdGlvbnNcbiAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgaWYgKCEhc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnJlbW92ZUFsbFZpZGVvcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzaWduYWxgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBzaWduYWw6VFlQRWA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2Ygc2lnbmFsIChjYW4gYmUgZW1wdHkpLlxuICAgICAqXG4gICAgICogVGhlIGNsaWVudCBtdXN0IGJlIHN1YnNjcmliZWQgdG8gYFNlc3Npb24ub24oJ3NpZ25hbDp0eXBlJywgZnVuY3Rpb24oc2lnbmFsRXZlbnQpIHsuLi59KWAgdG8gcmVjZWl2ZSB0aGlzIG9iamVjdCBpbiB0aGUgY2FsbGJhY2suXG4gICAgICpcbiAgICAgKiBTdWJzY3JpYmluZyB0byBgU2Vzc2lvbi5vbignc2lnbmFsJywgZnVuY3Rpb24oc2lnbmFsRXZlbnQpIHsuLi59KWAgd2lsbCB0cmlnZ2VyIGFsbCB0eXBlcyBvZiBzaWduYWxzLlxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBtZXNzYWdlIG9mIHRoZSBzaWduYWwgKGNhbiBiZSBlbXRweSlcbiAgICAgKi9cbiAgICBkYXRhOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc2VudCB0aGUgc2lnbmFsXG4gICAgICovXG4gICAgZnJvbTogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgZGF0YTogc3RyaW5nLCBmcm9tOiBDb25uZWN0aW9uKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9QdWJsaXNoZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1DcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhbmQgW1tQdWJsaXNoZXJdXVxuICogLSBgc3RyZWFtRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhbmQgW1tQdWJsaXNoZXJdXVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW0gb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBGb3IgJ3N0cmVhbURlc3Ryb3llZCcgZXZlbnQ6XG4gICAgICogLSBcInVucHVibGlzaFwiOiBtZXRob2QgYFNlc3Npb24udW5wdWJsaXNoKClgIGhhcyBiZWVuIGNhbGxlZFxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IG1ldGhvZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgIGhhcyBiZWVuIGNhbGxlZFxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZVVucHVibGlzaCgpYCBvdmVyIHRoZSBTdHJlYW1cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYCBvdmVyIHRoZSBTdHJlYW1cbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVNlcnZlclwiOiB0aGUgdXNlcidzIHN0cmVhbSBoYXMgYmVlbiB1bnB1Ymxpc2hlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHRoZSB1c2VyJ3MgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgbm8gbWVkaWEgc3RyZWFtcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBtZWRpYSBzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEZvciAnc3RyZWFtQ3JlYXRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgUHVibGlzaGVyLCB0eXBlOiBzdHJpbmcsIHN0cmVhbTogU3RyZWFtLCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihjYW5jZWxhYmxlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdzdHJlYW1EZXN0cm95ZWQnKSB7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdGUgU3RyZWFtXG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgUHVibGlzaGVyKSB7XG4gICAgICAgICAgICAgICAgLy8gTG9jYWwgU3RyZWFtXG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1B1Ymxpc2hlcidcIik7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCgoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkuc2NyZWVuU2hhcmVSZXNpemVJbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgUHVibGlzaGVyIG9iamVjdCBmcm9tIE9wZW5WaWR1IHB1Ymxpc2hlcnMgYXJyYXlcbiAgICAgICAgICAgICAgICBjb25zdCBvcGVudmlkdVB1Ymxpc2hlcnMgPSAoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkub3BlbnZpZHUucHVibGlzaGVycztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wZW52aWR1UHVibGlzaGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlbnZpZHVQdWJsaXNoZXJzW2ldID09PSAoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wZW52aWR1UHVibGlzaGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGlzcG9zZSB0aGUgTWVkaWFTdHJlYW0gbG9jYWwgb2JqZWN0XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gRE9NIGFsbCB2aWRlbyBlbGVtZW50cyBhc3NvY2lhdGVkIHRvIHRoaXMgU3RyZWFtLCBpZiB0aGVyZSdzIGEgU3RyZWFtTWFuYWdlciBkZWZpbmVkXG4gICAgICAgICAgICAvLyAobWV0aG9kIFNlc3Npb24uc3Vic2NyaWJlIG11c3QgaGF2ZSBiZWVuIGNhbGxlZClcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnJlbW92ZUFsbFZpZGVvcygpO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgc3RyZWFtIGZyb20gU2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZCBtYXBcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3RoaXMuc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIFN0cmVhbU9wdGlvbnNTZXJ2ZXIgZnJvbSByZW1vdGUgQ29ubmVjdGlvblxuICAgICAgICAgICAgY29uc3QgcmVtb3RlQ29ubmVjdGlvbiA9IHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbiAmJiAhIXJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbU9wdGlvbnNTZXJ2ZXIgPSByZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMuc3RyZWFtcztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gc3RyZWFtT3B0aW9uc1NlcnZlci5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyZWFtT3B0aW9uc1NlcnZlcltpXS5pZCA9PT0gdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbU9wdGlvbnNTZXJ2ZXIuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbVBsYXlpbmdgOiBkaXNwYXRjaGVkIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkgd2hlbmV2ZXIgaXRzIG1lZGlhIHN0cmVhbSBzdGFydHMgcGxheWluZyAob25lIG9mIGl0cyB2aWRlb3MgaGFzIG1lZGlhXG4gKiBhbmQgaGFzIGJlZ3VuIHRvIHBsYXkpLiBUaGlzIGV2ZW50IHdpbGwgYmUgZGlzcGF0Y2hlZCB3aGVuIHRoZXNlIDMgY29uZGl0aW9ucyBhcmUgbWV0IDEpIFRoZSBTdHJlYW1NYW5hZ2VyIGhhcyBubyB2aWRlbyBhc3NvY2lhdGVkIGluIHRoZSBET00gMikgSXQgaXMgYXNzb2NpYXRlZCB0byBvbmUgdmlkZW8gMykgVGhhdCB2aWRlbyBzdGFydHMgcGxheWluZ1xuICogLSBgc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VgOiBkaXNwYXRjaGVkIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkgd2hlbiB0aGUgdm9sdW1lIG9mIGl0cyBTdHJlYW0ncyBhdWRpbyB0cmFja1xuICogY2hhbmdlcy4gT25seSBhcHBsaWVzIGlmIFtbU3RyZWFtLmhhc0F1ZGlvXV0gaXMgYHRydWVgLiBUaGUgZnJlcXVlbmN5IHRoaXMgZXZlbnQgaXMgZmlyZWQgd2l0aCBpcyBkZWZpbmVkIGJ5IHByb3BlcnR5IGBpbnRlcnZhbGAgb2ZcbiAqIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zXV0gKGRlZmF1bHQgNTBtcylcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbU1hbmFnZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIEZvciBgc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VgIGV2ZW50OlxuICAgICAqIC0gYHtuZXdWYWx1ZTogbnVtYmVyLCBvbGRWYWx1ZTogbnVtYmVyfWA6IG5ldyBhbmQgb2xkIGF1ZGlvIHZvbHVtZSB2YWx1ZXMuIFRoZXNlIHZhbHVlcyBhcmUgYmV0d2VlbiAtMTAwIChzaWxlbmNlKSBhbmQgMCAobG91ZGVzdCBwb3NzaWJsZSB2b2x1bWUpLlxuICAgICAqIFRoZXkgYXJlIG5vdCBleGFjdCBhbmQgZGVwZW5kIG9uIGhvdyB0aGUgYnJvd3NlciBpcyBtYW5hZ2luZyB0aGUgYXVkaW8gdHJhY2ssIGJ1dCAtMTAwIGFuZCAwIGNhbiBiZSB0YWtlbiBhcyBsaW1pdCB2YWx1ZXMuXG4gICAgICogXG4gICAgICogRm9yIGBzdHJlYW1QbGF5aW5nYCBldmVudCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU3RyZWFtTWFuYWdlciwgdHlwZTogc3RyaW5nLCB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogRGVmaW5lcyBldmVudCBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFzIHdlbGwgYXMgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKS5cbiAqIFRoaXMgZXZlbnQgaXMgZmlyZWQgd2hlbiBhbnkgcmVtb3RlIHN0cmVhbSAob3duZWQgYnkgYSBTdWJzY3JpYmVyKSBvciBsb2NhbCBzdHJlYW0gKG93bmVkIGJ5IGEgUHVibGlzaGVyKSB1bmRlcmdvZXNcbiAqIGFueSBjaGFuZ2UgaW4gYW55IG9mIGl0cyBtdXRhYmxlIHByb3BlcnRpZXMgKHNlZSBbW2NoYW5nZWRQcm9wZXJ0eV1dKS5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVGhlIFN0cmVhbSB3aG9zZSBwcm9wZXJ0eSBoYXMgY2hhbmdlZC4gWW91IGNhbiBhbHdheXMgaWRlbnRpZnkgdGhlIHVzZXIgcHVibGlzaGluZyB0aGUgY2hhbmdlZCBzdHJlYW0gYnkgY29uc3VsdGluZyBwcm9wZXJ0eSBbW1N0cmVhbS5jb25uZWN0aW9uXV1cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9wZXJ0eSBvZiB0aGUgc3RyZWFtIHRoYXQgY2hhbmdlZC4gVGhpcyB2YWx1ZSBpcyBlaXRoZXIgYFwidmlkZW9BY3RpdmVcImAsIGBcImF1ZGlvQWN0aXZlXCJgLCBgXCJ2aWRlb0RpbWVuc2lvbnNcImAgb3IgYFwiZmlsdGVyXCJgXG4gICAgICovXG4gICAgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDYXVzZSBvZiB0aGUgY2hhbmdlIG9uIHRoZSBzdHJlYW0ncyBwcm9wZXJ0eTpcbiAgICAgKiAtIEZvciBgdmlkZW9BY3RpdmVgOiBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiAtIEZvciBgYXVkaW9BY3RpdmVgOiBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiAtIEZvciBgdmlkZW9EaW1lbnNpb25zYDogYFwiZGV2aWNlUm90YXRlZFwiYCBvciBgXCJzY3JlZW5SZXNpemVkXCJgXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBOZXcgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChhZnRlciBjaGFuZ2UsIGN1cnJlbnQgdmFsdWUpXG4gICAgICovXG4gICAgbmV3VmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIFByZXZpb3VzIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYmVmb3JlIGNoYW5nZSlcbiAgICAgKi9cbiAgICBvbGRWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIsIHN0cmVhbTogU3RyZWFtLCBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZywgbmV3VmFsdWU6IE9iamVjdCwgb2xkVmFsdWU6IE9iamVjdCwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcpO1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkUHJvcGVydHkgPSBjaGFuZ2VkUHJvcGVydHk7XG4gICAgICAgIHRoaXMubmV3VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHZpZGVvRWxlbWVudENyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGEgbmV3IEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBpbnNlcnRlZCBpbnRvIERPTSBieSBPcGVuVmlkdSBCcm93c2VyIGxpYnJhcnkuIFNlZVxuICogW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uLlxuICogLSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhbiBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIERPTSBieSBPcGVuVmlkdSBCcm93c2VyIGxpYnJhcnkuXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWRlb0VsZW1lbnRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGVsZW1lbnQgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQsIHRhcmdldDogU3RyZWFtTWFuYWdlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCJmdW5jdGlvbiBNYXBwZXIoKVxue1xuICB2YXIgc291cmNlcyA9IHt9O1xuXG5cbiAgdGhpcy5mb3JFYWNoID0gZnVuY3Rpb24oY2FsbGJhY2spXG4gIHtcbiAgICBmb3IodmFyIGtleSBpbiBzb3VyY2VzKVxuICAgIHtcbiAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2tleV07XG5cbiAgICAgIGZvcih2YXIga2V5MiBpbiBzb3VyY2UpXG4gICAgICAgIGNhbGxiYWNrKHNvdXJjZVtrZXkyXSk7XG4gICAgfTtcbiAgfTtcblxuICB0aGlzLmdldCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIGlkc1tpZF07XG4gIH07XG5cbiAgdGhpcy5yZW1vdmUgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuO1xuXG4gICAgZGVsZXRlIGlkc1tpZF07XG5cbiAgICAvLyBDaGVjayBpdCdzIGVtcHR5XG4gICAgZm9yKHZhciBpIGluIGlkcyl7cmV0dXJuIGZhbHNlfVxuXG4gICAgZGVsZXRlIHNvdXJjZXNbc291cmNlXTtcbiAgfTtcblxuICB0aGlzLnNldCA9IGZ1bmN0aW9uKHZhbHVlLCBpZCwgc291cmNlKVxuICB7XG4gICAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlKGlkLCBzb3VyY2UpO1xuXG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgc291cmNlc1tzb3VyY2VdID0gaWRzID0ge307XG5cbiAgICBpZHNbaWRdID0gdmFsdWU7XG4gIH07XG59O1xuXG5cbk1hcHBlci5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbntcbiAgdmFyIHZhbHVlID0gdGhpcy5nZXQoaWQsIHNvdXJjZSk7XG4gIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIHRoaXMucmVtb3ZlKGlkLCBzb3VyY2UpO1xuXG4gIHJldHVybiB2YWx1ZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXBwZXI7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIEpzb25ScGNDbGllbnQgID0gcmVxdWlyZSgnLi9qc29ucnBjY2xpZW50Jyk7XG5cblxuZXhwb3J0cy5Kc29uUnBjQ2xpZW50ICA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vJyk7XG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cbkRhdGUubm93ID0gRGF0ZS5ub3cgfHwgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiArbmV3IERhdGU7XG59O1xuXG52YXIgUElOR19JTlRFUlZBTCA9IDUwMDA7XG5cbnZhciBSRUNPTk5FQ1RJTkcgPSAnUkVDT05ORUNUSU5HJztcbnZhciBDT05ORUNURUQgPSAnQ09OTkVDVEVEJztcbnZhciBESVNDT05ORUNURUQgPSAnRElTQ09OTkVDVEVEJztcblxudmFyIExvZ2dlciA9IGNvbnNvbGU7XG5cbi8qKlxuICpcbiAqIGhlYXJ0YmVhdDogaW50ZXJ2YWwgaW4gbXMgZm9yIGVhY2ggaGVhcnRiZWF0IG1lc3NhZ2UsXG4gKiBzZW5kQ2xvc2VNZXNzYWdlIDogdHJ1ZSAvIGZhbHNlLCBiZWZvcmUgY2xvc2luZyB0aGUgY29ubmVjdGlvbiwgaXQgc2VuZHMgYSBjbG9zZVNlc3Npb24gbWVzc2FnZVxuICogPHByZT5cbiAqIHdzIDoge1xuICogXHR1cmkgOiBVUkkgdG8gY29ubnRlY3QgdG8sXG4gKiAgdXNlU29ja0pTIDogdHJ1ZSAodXNlIFNvY2tKUykgLyBmYWxzZSAodXNlIFdlYlNvY2tldCkgYnkgZGVmYXVsdCxcbiAqIFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuICogXHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcbiAqIFx0b25yZWNvbm5lY3RpbmcgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBpcyByZWNvbm5lY3RpbmcsXG4gKiBcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcbiAqIFx0b25lcnJvciA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGVyZSBpcyBhbiBlcnJvclxuICogfSxcbiAqIHJwYyA6IHtcbiAqIFx0cmVxdWVzdFRpbWVvdXQgOiB0aW1lb3V0IGZvciBhIHJlcXVlc3QsXG4gKiBcdHNlc3Npb25TdGF0dXNDaGFuZ2VkOiBjYWxsYmFjayBtZXRob2QgZm9yIGNoYW5nZXMgaW4gc2Vzc2lvbiBzdGF0dXMsXG4gKiBcdG1lZGlhUmVuZWdvdGlhdGlvbjogbWVkaWFSZW5lZ290aWF0aW9uXG4gKiB9XG4gKiA8L3ByZT5cbiAqL1xuZnVuY3Rpb24gSnNvblJwY0NsaWVudChjb25maWd1cmF0aW9uKSB7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgd3NDb25maWcgPSBjb25maWd1cmF0aW9uLndzO1xuXG4gICAgdmFyIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSAtMTtcblxuICAgIHZhciBwaW5nTmV4dE51bSA9IDA7XG4gICAgdmFyIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgdmFyIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgIHZhciBwaW5nSW50ZXJ2YWw7XG5cbiAgICB2YXIgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgdmFyIG9ucmVjb25uZWN0aW5nID0gd3NDb25maWcub25yZWNvbm5lY3Rpbmc7XG4gICAgdmFyIG9ucmVjb25uZWN0ZWQgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGVkO1xuICAgIHZhciBvbmNvbm5lY3RlZCA9IHdzQ29uZmlnLm9uY29ubmVjdGVkO1xuICAgIHZhciBvbmVycm9yID0gd3NDb25maWcub25lcnJvcjtcblxuICAgIGNvbmZpZ3VyYXRpb24ucnBjLnB1bGwgPSBmdW5jdGlvbiAocGFyYW1zLCByZXF1ZXN0KSB7XG4gICAgICAgIHJlcXVlc3QucmVwbHkobnVsbCwgXCJwdXNoXCIpO1xuICAgIH1cblxuICAgIHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RJTkcgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IFJFQ09OTkVDVElORykge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gUkVDT05ORUNUSU5HIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNUSU5HIG1lc3NhZ2UuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RvcFBpbmcoKTtcblxuICAgICAgICBzdGF0dXMgPSBSRUNPTk5FQ1RJTkc7XG4gICAgICAgIGlmIChvbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVEVEIG1lc3NhZ2UuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG5cbiAgICAgICAgaWYgKG9ucmVjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05DT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OQ09OTkVDVEVEIG1lc3NhZ2UuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICB1c2VQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05FUlJPUiAtLS0tLS0tLS0tLVwiKTtcblxuICAgICAgICBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICAgICAgc3RvcFBpbmcoKTtcblxuICAgICAgICBpZiAob25lcnJvcikge1xuICAgICAgICAgICAgb25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgd3MgPSBuZXcgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbih3c0NvbmZpZyk7XG5cbiAgICBMb2dnZXIuZGVidWcoJ0Nvbm5lY3Rpbmcgd2Vic29ja2V0IHRvIFVSSTogJyArIHdzQ29uZmlnLnVyaSk7XG5cbiAgICB2YXIgcnBjQnVpbGRlck9wdGlvbnMgPSB7XG4gICAgICAgIHJlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMucmVxdWVzdFRpbWVvdXQsXG4gICAgICAgIHBpbmdfcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5oZWFydGJlYXRSZXF1ZXN0VGltZW91dFxuICAgIH07XG5cbiAgICB2YXIgcnBjID0gbmV3IFJwY0J1aWxkZXIoUnBjQnVpbGRlci5wYWNrZXJzLkpzb25SUEMsIHJwY0J1aWxkZXJPcHRpb25zLCB3cyxcbiAgICAgICAgZnVuY3Rpb24gKHJlcXVlc3QpIHtcblxuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZWNlaXZlZCByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBmdW5jID0gY29uZmlndXJhdGlvbi5ycGNbcmVxdWVzdC5tZXRob2RdO1xuXG4gICAgICAgICAgICAgICAgaWYgKGZ1bmMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJNZXRob2QgXCIgKyByZXF1ZXN0Lm1ldGhvZCArIFwiIG5vdCByZWdpc3RlcmVkIGluIGNsaWVudFwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmdW5jKHJlcXVlc3QucGFyYW1zLCByZXF1ZXN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ0V4Y2VwdGlvbiBwcm9jZXNzaW5nIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAobWV0aG9kICE9PSAncGluZycpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVxdWVzdDogbWV0aG9kOicgKyBtZXRob2QgKyBcIiBwYXJhbXM6XCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcnBjLmVuY29kZShtZXRob2QsIHBhcmFtcywgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIkVSUk9SOlwiICsgZXJyb3IubWVzc2FnZSArIFwiIGluIFJlcXVlc3Q6IG1ldGhvZDpcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgKyBcIiBwYXJhbXM6XCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgXCIgcmVxdWVzdDpcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIkVSUk9SIERBVEE6XCIgKyBKU09OLnN0cmluZ2lmeShlcnJvci5kYXRhKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3RUaW1lID0gcmVxdWVzdFRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IHVuZGVmaW5lZCAmJiByZXN1bHQudmFsdWUgIT09ICdwb25nJykge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1Jlc3BvbnNlOiAnICsgSlNPTi5zdHJpbmdpZnkocmVzdWx0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gXCIgKyBwaW5nTmV4dE51bSArICcgKG9sZD0nICtcbiAgICAgICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gKyAnKScpO1xuICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gcGluZ05leHROdW07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VuZFBpbmcoKSB7XG4gICAgICAgIGlmIChlbmFibGVkUGluZ3MpIHtcbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHBpbmdOZXh0TnVtID09IDAgfHwgcGluZ05leHROdW0gPT0gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0IHx8IFBJTkdfSU5URVJWQUxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGluZ05leHROdW0rKztcblxuICAgICAgICAgICAgc2VsZi5zZW5kKCdwaW5nJywgcGFyYW1zLCAoZnVuY3Rpb24gKHBpbmdOdW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJFcnJvciBpbiBwaW5nIHJlcXVlc3QgI1wiICsgcGluZ051bSArIFwiIChcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubWVzc2FnZSArIFwiKVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaW5nTnVtID4gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZXJ2ZXIgZGlkIG5vdCByZXNwb25kIHRvIHBpbmcgbWVzc2FnZSAjXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5nTnVtICsgXCIuIFJlY29ubmVjdGluZy4uLiBcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKHBpbmdOZXh0TnVtKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUcnlpbmcgdG8gc2VuZCBwaW5nLCBidXQgcGluZyBpcyBub3QgZW5hYmxlZFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgICogSWYgY29uZmlndXJhdGlvbi5oZWFyYmVhdCBoYXMgYW55IHZhbHVlLCB0aGUgcGluZy1wb25nIHdpbGwgd29yayB3aXRoIHRoZSBpbnRlcnZhbFxuICAgICAqIG9mIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1c2VQaW5nKCkge1xuICAgICAgICBpZiAoIXBpbmdQb25nU3RhcnRlZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU3RhcnRpbmcgcGluZyAoaWYgY29uZmlndXJlZClcIilcbiAgICAgICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwaW5nSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChzZW5kUGluZywgY29uZmlndXJhdGlvbi5oZWFydGJlYXQpO1xuICAgICAgICAgICAgICAgIHNlbmRQaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdG9wUGluZygpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gLTE7XG4gICAgICAgIHJwYy5jYW5jZWwoKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKGNvZGUsIHJlYXNvbikge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJDbG9zaW5nICB3aXRoIGNvZGU6IFwiICsgY29kZSArIFwiIGJlY2F1c2U6IFwiICsgcmVhc29uKTtcblxuICAgICAgICBpZiAocGluZ0ludGVydmFsICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xlYXJpbmcgcGluZyBpbnRlcnZhbFwiKTtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgfVxuICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uc2VuZENsb3NlTWVzc2FnZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VuZGluZyBjbG9zZSBtZXNzYWdlXCIpXG4gICAgICAgICAgICB0aGlzLnNlbmQoJ2Nsb3NlU2Vzc2lvbicsIG51bGwsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgY2xvc2UgbWVzc2FnZTogXCIgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB3cy5jbG9zZShjb2RlLCByZWFzb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3cy5jbG9zZShjb2RlLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhpcyBtZXRob2QgaXMgb25seSBmb3IgdGVzdGluZ1xuICAgIHRoaXMuZm9yY2VDbG9zZSA9IGZ1bmN0aW9uIChtaWxsaXMpIHtcbiAgICAgICAgd3MuZm9yY2VDbG9zZShtaWxsaXMpO1xuICAgIH1cblxuICAgIHRoaXMucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRQaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IDA7XG4gICAgICAgIHVzZVBpbmcoKTtcbiAgICB9XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSByZXF1aXJlKCcuL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuXG5leHBvcnRzLldlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbjsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDEzLTIwMTUgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgQnJvd3NlcldlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcblxudmFyIExvZ2dlciA9IGNvbnNvbGU7XG5cbi8qKlxuICogR2V0IGVpdGhlciB0aGUgYFdlYlNvY2tldGAgb3IgYE1veldlYlNvY2tldGAgZ2xvYmFsc1xuICogaW4gdGhlIGJyb3dzZXIgb3IgdHJ5IHRvIHJlc29sdmUgV2ViU29ja2V0LWNvbXBhdGlibGVcbiAqIGludGVyZmFjZSBleHBvc2VkIGJ5IGB3c2AgZm9yIE5vZGUtbGlrZSBlbnZpcm9ubWVudC5cbiAqL1xuXG4vKnZhciBXZWJTb2NrZXQgPSBCcm93c2VyV2ViU29ja2V0O1xuaWYgKCFXZWJTb2NrZXQgJiYgdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0cnkge1xuICAgICAgICBXZWJTb2NrZXQgPSByZXF1aXJlKCd3cycpO1xuICAgIH0gY2F0Y2ggKGUpIHsgfVxufSovXG5cbi8vdmFyIFNvY2tKUyA9IHJlcXVpcmUoJ3NvY2tqcy1jbGllbnQnKTtcblxudmFyIE1BWF9SRVRSSUVTID0gMjAwMDsgLy8gRm9yZXZlci4uLlxudmFyIFJFVFJZX1RJTUVfTVMgPSAzMDAwOyAvLyBGSVhNRTogSW1wbGVtZW50IGV4cG9uZW50aWFsIHdhaXQgdGltZXMuLi5cblxudmFyIENPTk5FQ1RJTkcgPSAwO1xudmFyIE9QRU4gPSAxO1xudmFyIENMT1NJTkcgPSAyO1xudmFyIENMT1NFRCA9IDM7XG5cbi8qXG5jb25maWcgPSB7XG5cdFx0dXJpIDogd3NVcmksXG5cdFx0dXNlU29ja0pTIDogdHJ1ZSAodXNlIFNvY2tKUykgLyBmYWxzZSAodXNlIFdlYlNvY2tldCkgYnkgZGVmYXVsdCxcblx0XHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG5cdFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG5cdFx0b25yZWNvbm5lY3RpbmcgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBpcyByZWNvbm5lY3RpbmcsXG5cdFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuXHR9O1xuKi9cbmZ1bmN0aW9uIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24oY29uZmlnKSB7XG5cbiAgICB2YXIgY2xvc2luZyA9IGZhbHNlO1xuICAgIHZhciByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyO1xuICAgIHZhciB3c1VyaSA9IGNvbmZpZy51cmk7XG4gICAgdmFyIHVzZVNvY2tKUyA9IGNvbmZpZy51c2VTb2NrSlM7XG4gICAgdmFyIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICB2YXIgd3M7XG5cbiAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgIHdzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICB9XG5cbiAgICB3cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxvZ0Nvbm5lY3RlZCh3cywgd3NVcmkpO1xuICAgICAgICBpZiAoY29uZmlnLm9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBjb25maWcub25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5lcnJvcihcIkNvdWxkIG5vdCBjb25uZWN0IHRvIFwiICsgd3NVcmkgKyBcIiAoaW52b2tpbmcgb25lcnJvciBpZiBkZWZpbmVkKVwiLCBlcnJvcik7XG4gICAgICAgIGlmIChjb25maWcub25lcnJvcikge1xuICAgICAgICAgICAgY29uZmlnLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGxvZ0Nvbm5lY3RlZCh3cywgd3NVcmkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIldlYlNvY2tldCBjb25uZWN0ZWQgdG8gXCIgKyB3c1VyaSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciByZWNvbm5lY3Rpb25PbkNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAod3MucmVhZHlTdGF0ZSA9PT0gQ0xPU0VEKSB7XG4gICAgICAgICAgICBpZiAoY2xvc2luZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIGJ5IHVzZXJcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIHVuZXhwZWN0ZWNseS4gUmVjb25uZWN0aW5nLi4uXCIpO1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbG9zZSBjYWxsYmFjayBmcm9tIHByZXZpb3VzIHdlYnNvY2tldC4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG5cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RUb1NhbWVVcmkgKGF0dGVtcHQgI1wiICsgbnVtUmV0cmllcyArIFwiLCBtYXg9XCIgKyBtYXhSZXRyaWVzICsgXCIpXCIpO1xuXG4gICAgICAgIGlmIChudW1SZXRyaWVzID09PSAxKSB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLndhcm4oXCJUcnlpbmcgdG8gcmVjb25uZWN0VG9OZXdVcmkgd2hlbiByZWNvbm5lY3RpbmcuLi4gSWdub3JpbmcgdGhpcyByZWNvbm5lY3Rpb24uXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZm9yY2luZ0Rpc2Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHdzVXJpKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24oZnVuY3Rpb24gKGVycm9yLCBuZXdXc1VyaSkge1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzICsgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIG5ld1dzVXJpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHdzVXJpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRPRE8gVGVzdCByZXRyaWVzLiBIb3cgdG8gZm9yY2Ugbm90IGNvbm5lY3Rpb24/XG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgcmVjb25uZWN0V3NVcmkpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0aW9uIGF0dGVtcHQgI1wiICsgbnVtUmV0cmllcyk7XG5cbiAgICAgICAgd3MuY2xvc2UoKTtcblxuICAgICAgICB3c1VyaSA9IHJlY29ubmVjdFdzVXJpIHx8IHdzVXJpO1xuXG4gICAgICAgIHZhciBuZXdXcztcbiAgICAgICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdXcy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3RlZCBhZnRlciBcIiArIG51bVJldHJpZXMgKyBcIiBhdHRlbXB0cy4uLlwiKTtcbiAgICAgICAgICAgIGxvZ0Nvbm5lY3RlZChuZXdXcywgd3NVcmkpO1xuICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGVkKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5ld1dzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBvbkVycm9yT3JDbG9zZSA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgTG9nZ2VyLndhcm4oXCJSZWNvbm5lY3Rpb24gZXJyb3I6IFwiLCBlcnJvcik7XG5cbiAgICAgICAgICAgIGlmIChudW1SZXRyaWVzID09PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5vbmRpc2Nvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLm9uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzICsgMSk7XG4gICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgbmV3V3Mub25lcnJvciA9IG9uRXJyb3JPckNsb3NlO1xuXG4gICAgICAgIHdzID0gbmV3V3M7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuXG4gICAgLy8gVGhpcyBtZXRob2QgaXMgb25seSBmb3IgdGVzdGluZ1xuICAgIHRoaXMuZm9yY2VDbG9zZSA9IGZ1bmN0aW9uIChtaWxsaXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogRm9yY2UgV2ViU29ja2V0IGNsb3NlXCIpO1xuXG4gICAgICAgIGlmIChtaWxsaXMpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IENoYW5nZSB3c1VyaSBmb3IgXCIgKyBtaWxsaXMgKyBcIiBtaWxsaXMgdG8gc2ltdWxhdGUgbmV0IGZhaWx1cmVcIik7XG4gICAgICAgICAgICB2YXIgZ29vZFdzVXJpID0gd3NVcmk7XG4gICAgICAgICAgICB3c1VyaSA9IFwid3NzOi8vMjEuMjM0LjEyLjM0LjQ6NDQzL1wiO1xuXG4gICAgICAgICAgICBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IHRydWU7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IFJlY292ZXIgZ29vZCB3c1VyaSBcIiArIGdvb2RXc1VyaSk7XG4gICAgICAgICAgICAgICAgd3NVcmkgPSBnb29kV3NVcmk7XG5cbiAgICAgICAgICAgICAgICBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgICAgICAgICB9LCBtaWxsaXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZWNvbm5lY3RXcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0V3NcIik7XG4gICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSk7XG4gICAgfTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIHdzLnNlbmQobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uICh0eXBlLCBjYWxsYmFjaykge1xuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjayk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbjsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuXG52YXIgZGVmaW5lUHJvcGVydHlfSUU4ID0gZmFsc2VcbmlmKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSlcbntcbiAgdHJ5XG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sIFwieFwiLCB7fSk7XG4gIH1cbiAgY2F0Y2goZSlcbiAge1xuICAgIGRlZmluZVByb3BlcnR5X0lFOCA9IHRydWVcbiAgfVxufVxuXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XG4gIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24ob1RoaXMpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIGNsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNVxuICAgICAgLy8gaW50ZXJuYWwgSXNDYWxsYWJsZSBmdW5jdGlvblxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcbiAgICB9XG5cbiAgICB2YXIgYUFyZ3MgICA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgIGZUb0JpbmQgPSB0aGlzLFxuICAgICAgICBmTk9QICAgID0gZnVuY3Rpb24oKSB7fSxcbiAgICAgICAgZkJvdW5kICA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBmVG9CaW5kLmFwcGx5KHRoaXMgaW5zdGFuY2VvZiBmTk9QICYmIG9UaGlzXG4gICAgICAgICAgICAgICAgID8gdGhpc1xuICAgICAgICAgICAgICAgICA6IG9UaGlzLFxuICAgICAgICAgICAgICAgICBhQXJncy5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgICB9O1xuXG4gICAgZk5PUC5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICBmQm91bmQucHJvdG90eXBlID0gbmV3IGZOT1AoKTtcblxuICAgIHJldHVybiBmQm91bmQ7XG4gIH07XG59XG5cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHBhY2tlcnMgPSByZXF1aXJlKCcuL3BhY2tlcnMnKTtcbnZhciBNYXBwZXIgPSByZXF1aXJlKCcuL01hcHBlcicpO1xuXG5cbnZhciBCQVNFX1RJTUVPVVQgPSA1MDAwO1xuXG5cbmZ1bmN0aW9uIHVuaWZ5UmVzcG9uc2VNZXRob2RzKHJlc3BvbnNlTWV0aG9kcylcbntcbiAgaWYoIXJlc3BvbnNlTWV0aG9kcykgcmV0dXJuIHt9O1xuXG4gIGZvcih2YXIga2V5IGluIHJlc3BvbnNlTWV0aG9kcylcbiAge1xuICAgIHZhciB2YWx1ZSA9IHJlc3BvbnNlTWV0aG9kc1trZXldO1xuXG4gICAgaWYodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKVxuICAgICAgcmVzcG9uc2VNZXRob2RzW2tleV0gPVxuICAgICAge1xuICAgICAgICByZXNwb25zZTogdmFsdWVcbiAgICAgIH1cbiAgfTtcblxuICByZXR1cm4gcmVzcG9uc2VNZXRob2RzO1xufTtcblxuZnVuY3Rpb24gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KVxue1xuICBpZighdHJhbnNwb3J0KSByZXR1cm47XG5cbiAgLy8gVHJhbnNwb3J0IGFzIGEgZnVuY3Rpb25cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHtzZW5kOiB0cmFuc3BvcnR9O1xuXG4gIC8vIFdlYlNvY2tldCAmIERhdGFDaGFubmVsXG4gIGlmKHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcblxuICAvLyBNZXNzYWdlIEFQSSAoSW50ZXItd2luZG93ICYgV2ViV29ya2VyKVxuICBpZih0cmFuc3BvcnQucG9zdE1lc3NhZ2UgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LnBvc3RNZXNzYWdlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBTdHJlYW0gQVBJXG4gIGlmKHRyYW5zcG9ydC53cml0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQud3JpdGU7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFRyYW5zcG9ydHMgdGhhdCBvbmx5IGNhbiByZWNlaXZlIG1lc3NhZ2VzLCBidXQgbm90IHNlbmRcbiAgaWYodHJhbnNwb3J0Lm9ubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gIGlmKHRyYW5zcG9ydC5wYXVzZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSByZXR1cm47XG5cbiAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVHJhbnNwb3J0IGlzIG5vdCBhIGZ1bmN0aW9uIG5vciBhIHZhbGlkIG9iamVjdFwiKTtcbn07XG5cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyBub3RpZmljYXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICovXG5mdW5jdGlvbiBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpXG57XG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAge1xuICAgIHRoaXMubWV0aG9kID0gbWV0aG9kXG4gICAgdGhpcy5wYXJhbXMgPSBwYXJhbXNcbiAgfVxuICBlbHNlXG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ21ldGhvZCcsIHt2YWx1ZTogbWV0aG9kLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwYXJhbXMnLCB7dmFsdWU6IHBhcmFtcywgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICB9XG59O1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHBhY2tlclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc11cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF1cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb25SZXF1ZXN0XVxuICovXG5mdW5jdGlvbiBScGNCdWlsZGVyKHBhY2tlciwgb3B0aW9ucywgdHJhbnNwb3J0LCBvblJlcXVlc3QpXG57XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZighcGFja2VyKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgaWYoIXBhY2tlci5wYWNrIHx8ICFwYWNrZXIudW5wYWNrKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIGludmFsaWQnKTtcblxuICB2YXIgcmVzcG9uc2VNZXRob2RzID0gdW5pZnlSZXNwb25zZU1ldGhvZHMocGFja2VyLnJlc3BvbnNlTWV0aG9kcyk7XG5cblxuICBpZihvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSBvcHRpb25zO1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYob3B0aW9ucyAmJiBvcHRpb25zLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAmJiAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYob25SZXF1ZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICBpZihvblJlcXVlc3QgJiYgIShvblJlcXVlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXG4gIEV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gIGlmKG9uUmVxdWVzdClcbiAgICB0aGlzLm9uKCdyZXF1ZXN0Jywgb25SZXF1ZXN0KTtcblxuXG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICB0aGlzLnBlZXJJRCA9IG9wdGlvbnMucGVlcklEXG4gIGVsc2VcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BlZXJJRCcsIHt2YWx1ZTogb3B0aW9ucy5wZWVySUR9KTtcblxuICB2YXIgbWF4X3JldHJpZXMgPSBvcHRpb25zLm1heF9yZXRyaWVzIHx8IDA7XG5cblxuICBmdW5jdGlvbiB0cmFuc3BvcnRNZXNzYWdlKGV2ZW50KVxuICB7XG4gICAgc2VsZi5kZWNvZGUoZXZlbnQuZGF0YSB8fCBldmVudCk7XG4gIH07XG5cbiAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gIHtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG4gIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gIHtcbiAgICAvLyBSZW1vdmUgbGlzdGVuZXIgZnJvbSBvbGQgdHJhbnNwb3J0XG4gICAgaWYodHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICAvLyBTZXQgbGlzdGVuZXIgb24gbmV3IHRyYW5zcG9ydFxuICAgIGlmKHZhbHVlKVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih2YWx1ZS5hZGRFdmVudExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodmFsdWUuYWRkTGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZExpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgfVxuXG4gIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgIHtcbiAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgIH0pXG5cbiAgdGhpcy5zZXRUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuXG4gIHZhciByZXF1ZXN0X3RpbWVvdXQgICAgICA9IG9wdGlvbnMucmVxdWVzdF90aW1lb3V0ICAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgcGluZ19yZXF1ZXN0X3RpbWVvdXQgPSBvcHRpb25zLnBpbmdfcmVxdWVzdF90aW1lb3V0IHx8IHJlcXVlc3RfdGltZW91dDtcbiAgdmFyIHJlc3BvbnNlX3RpbWVvdXQgICAgID0gb3B0aW9ucy5yZXNwb25zZV90aW1lb3V0ICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBkdXBsaWNhdGVzX3RpbWVvdXQgICA9IG9wdGlvbnMuZHVwbGljYXRlc190aW1lb3V0ICAgfHwgQkFTRV9USU1FT1VUO1xuXG5cbiAgdmFyIHJlcXVlc3RJRCA9IDA7XG5cbiAgdmFyIHJlcXVlc3RzICA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcblxuICB2YXIgbWVzc2FnZTJLZXkgPSB7fTtcblxuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGR1cGxpY2F0ZSByZXF1ZXN0IGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBkZXN0KVxuICB7XG4gICAgdmFyIHJlc3BvbnNlID1cbiAgICB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgLyoqIFRpbWVvdXQgdG8gYXV0by1jbGVhbiBvbGQgcmVzcG9uc2VzICovXG4gICAgICB0aW1lb3V0OiBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2VzLnJlbW92ZShpZCwgZGVzdCk7XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2VfdGltZW91dClcbiAgICB9O1xuXG4gICAgcmVzcG9uc2VzLnNldChyZXNwb25zZSwgaWQsIGRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gaWdub3JlIGR1cGxpY2F0ZWQgbWVzc2FnZXMgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKVxuICB7XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICBwcm9jZXNzZWRSZXNwb25zZXMucmVtb3ZlKGFjaywgZnJvbSk7XG4gICAgfSxcbiAgICBkdXBsaWNhdGVzX3RpbWVvdXQpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnNldCh0aW1lb3V0LCBhY2ssIGZyb20pO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIHJlcXVlc3RcbiAgICpcbiAgICogQGNsYXNzXG4gICAqIEBleHRlbmRzIFJwY05vdGlmaWNhdGlvblxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gaWRlbnRpZmllciBvZiB0aGUgcmVxdWVzdFxuICAgKiBAcGFyYW0gW2Zyb21dIC0gc291cmNlIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICovXG4gIGZ1bmN0aW9uIFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkLCBmcm9tLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBScGNOb3RpZmljYXRpb24uY2FsbCh0aGlzLCBtZXRob2QsIHBhcmFtcyk7XG5cbiAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cbiAgICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICAgIHtcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgICAge1xuICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgICAgfSlcblxuICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuXG4gICAgLyoqXG4gICAgICogQGNvbnN0YW50IHtCb29sZWFufSBkdXBsaWNhdGVkXG4gICAgICovXG4gICAgaWYoISh0cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKSkpXG4gICAge1xuICAgICAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgICB0aGlzLmR1cGxpY2F0ZWQgPSBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgZWxzZVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2R1cGxpY2F0ZWQnLFxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciByZXNwb25zZU1ldGhvZCA9IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdO1xuXG4gICAgdGhpcy5wYWNrID0gcGFja2VyLnBhY2suYmluZChwYWNrZXIsIHRoaXMsIGlkKVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3RcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J9IFtlcnJvcl1cbiAgICAgKiBAcGFyYW0geyp9IFtyZXN1bHRdXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMucmVwbHkgPSBmdW5jdGlvbihlcnJvciwgcmVzdWx0LCB0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgZXJyb3IgJiYgZXJyb3Iuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZihyZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gZXJyb3I7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIGVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBlbHNlIGlmKHJlc3VsdCBpbnN0YW5jZW9mIEZ1bmN0aW9uXG4gICAgICB8fCByZXN1bHQgJiYgcmVzdWx0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIC8vIER1cGxpY2F0ZWQgcmVxdWVzdCwgcmVtb3ZlIG9sZCByZXNwb25zZSB0aW1lb3V0XG4gICAgICBpZihyZXNwb25zZSlcbiAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlLnRpbWVvdXQpO1xuXG4gICAgICBpZihmcm9tICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgZXJyb3IuZGVzdCA9IGZyb207XG5cbiAgICAgICAgaWYocmVzdWx0KVxuICAgICAgICAgIHJlc3VsdC5kZXN0ID0gZnJvbTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBtZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgcmVxdWVzdCBvciBvdmVycmlkZW4gb25lLCBjcmVhdGUgbmV3IHJlc3BvbnNlIHdpdGggcHJvdmlkZWQgZGF0YVxuICAgICAgaWYoZXJyb3IgfHwgcmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgICAgICB7XG4gICAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgICBlcnJvci5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVzdWx0LmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb3RvY29sIGluZGljYXRlcyB0aGF0IHJlc3BvbnNlcyBoYXMgb3duIHJlcXVlc3QgbWV0aG9kc1xuICAgICAgICBpZihyZXNwb25zZU1ldGhvZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kLmVycm9yID09IHVuZGVmaW5lZCAmJiBlcnJvcilcbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlcnJvcjogZXJyb3JcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICBlbHNlXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgID8gcmVzcG9uc2VNZXRob2QuZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgOiByZXNwb25zZU1ldGhvZC5yZXNwb25zZTtcblxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICBwYXJhbXM6IGVycm9yIHx8IHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yOiAgZXJyb3IsXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICAgIH07XG5cbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRHVwbGljYXRlICYgbm90LW92ZXJyaWRlbiByZXF1ZXN0LCByZS1zZW5kIG9sZCByZXNwb25zZVxuICAgICAgZWxzZSBpZihyZXNwb25zZSlcbiAgICAgICAgbWVzc2FnZSA9IHJlc3BvbnNlLm1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyBlbXB0eSByZXBseSwgcmVzcG9uc2UgbnVsbCB2YWx1ZVxuICAgICAgZWxzZVxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2soe3Jlc3VsdDogbnVsbH0sIGlkKTtcblxuICAgICAgLy8gU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCBsYXRlclxuICAgICAgc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZnJvbSk7XG5cbiAgICAgIC8vIFJldHVybiB0aGUgc3RvcmVkIHJlc3BvbnNlIHNvIGl0IGNhbiBiZSBkaXJlY3RseSBzZW5kIGJhY2tcbiAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpIHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG5cbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG4gIH07XG4gIGluaGVyaXRzKFJwY1JlcXVlc3QsIFJwY05vdGlmaWNhdGlvbik7XG5cblxuICBmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSlcbiAge1xuICAgIHZhciBrZXkgPSBtZXNzYWdlMktleVttZXNzYWdlXTtcbiAgICBpZigha2V5KSByZXR1cm47XG5cbiAgICBkZWxldGUgbWVzc2FnZTJLZXlbbWVzc2FnZV07XG5cbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLnBvcChrZXkuaWQsIGtleS5kZXN0KTtcbiAgICBpZighcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgY2xlYXJUaW1lb3V0KHJlcXVlc3QudGltZW91dCk7XG5cbiAgICAvLyBTdGFydCBkdXBsaWNhdGVkIHJlc3BvbnNlcyB0aW1lb3V0XG4gICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShrZXkuaWQsIGtleS5kZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogQWxsb3cgdG8gY2FuY2VsIGEgcmVxdWVzdCBhbmQgZG9uJ3Qgd2FpdCBmb3IgYSByZXNwb25zZVxuICAgKlxuICAgKiBJZiBgbWVzc2FnZWAgaXMgbm90IGdpdmVuLCBjYW5jZWwgYWxsIHRoZSByZXF1ZXN0XG4gICAqL1xuICB0aGlzLmNhbmNlbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpXG4gIHtcbiAgICBpZihtZXNzYWdlKSByZXR1cm4gY2FuY2VsKG1lc3NhZ2UpO1xuXG4gICAgZm9yKHZhciBtZXNzYWdlIGluIG1lc3NhZ2UyS2V5KVxuICAgICAgY2FuY2VsKG1lc3NhZ2UpO1xuICB9O1xuXG5cbiAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uKClcbiAge1xuICAgIC8vIFByZXZlbnQgdG8gcmVjZWl2ZSBuZXcgbWVzc2FnZXNcbiAgICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LmNsb3NlKVxuICAgICAgdHJhbnNwb3J0LmNsb3NlKDQwMDMsIFwiQ2FuY2VsIHJlcXVlc3RcIik7XG5cbiAgICAvLyBSZXF1ZXN0ICYgcHJvY2Vzc2VkIHJlc3BvbnNlc1xuICAgIHRoaXMuY2FuY2VsKCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuZm9yRWFjaChjbGVhclRpbWVvdXQpO1xuXG4gICAgLy8gUmVzcG9uc2VzXG4gICAgcmVzcG9uc2VzLmZvckVhY2goZnVuY3Rpb24ocmVzcG9uc2UpXG4gICAge1xuICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlLnRpbWVvdXQpO1xuICAgIH0pO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhbmQgZW5jb2RlIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBbZGVzdF0gLSBkZXN0aW5hdGlvbiBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XSAtIHRyYW5zcG9ydCB3aGVyZSB0byBzZW5kIHRoZSBtZXNzYWdlXG4gICAqIEBwYXJhbSBbY2FsbGJhY2tdIC0gZnVuY3Rpb24gY2FsbGVkIHdoZW4gYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3QgaXNcbiAgICogICByZWNlaXZlZC4gSWYgbm90IGRlZmluZWQsIGEgbm90aWZpY2F0aW9uIHdpbGwgYmUgc2VuZCBpbnN0ZWFkXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IEEgcmF3IEpzb25SUEMgMi4wIHJlcXVlc3Qgb3Igbm90aWZpY2F0aW9uIHN0cmluZ1xuICAgKi9cbiAgdGhpcy5lbmNvZGUgPSBmdW5jdGlvbihtZXRob2QsIHBhcmFtcywgZGVzdCwgdHJhbnNwb3J0LCBjYWxsYmFjaylcbiAge1xuICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgaWYocGFyYW1zIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHBhcmFtcztcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICAgIHBhcmFtcyAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKGRlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBkZXN0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYoY2FsbGJhY2sgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSB0cmFuc3BvcnQ7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgfTtcblxuICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmRlc3QgPSBkZXN0O1xuICAgIH07XG5cbiAgICAvLyBFbmNvZGUgbWVzc2FnZVxuICAgIHZhciBtZXNzYWdlID1cbiAgICB7XG4gICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgIHBhcmFtczogcGFyYW1zXG4gICAgfTtcblxuICAgIGlmKGNhbGxiYWNrKVxuICAgIHtcbiAgICAgIHZhciBpZCA9IHJlcXVlc3RJRCsrO1xuICAgICAgdmFyIHJldHJpZWQgPSAwO1xuXG4gICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuXG4gICAgICBmdW5jdGlvbiBkaXNwYXRjaENhbGxiYWNrKGVycm9yLCByZXN1bHQpXG4gICAgICB7XG4gICAgICAgIHNlbGYuY2FuY2VsKG1lc3NhZ2UpO1xuXG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgfTtcblxuICAgICAgdmFyIHJlcXVlc3QgPVxuICAgICAge1xuICAgICAgICBtZXNzYWdlOiAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgIGNhbGxiYWNrOiAgICAgICAgZGlzcGF0Y2hDYWxsYmFjayxcbiAgICAgICAgcmVzcG9uc2VNZXRob2RzOiByZXNwb25zZU1ldGhvZHNbbWV0aG9kXSB8fCB7fVxuICAgICAgfTtcblxuICAgICAgdmFyIGVuY29kZV90cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICBmdW5jdGlvbiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHZhciBydCA9IChtZXRob2QgPT09ICdwaW5nJyA/IHBpbmdfcmVxdWVzdF90aW1lb3V0IDogcmVxdWVzdF90aW1lb3V0KTtcbiAgICAgICAgcmVxdWVzdC50aW1lb3V0ID0gc2V0VGltZW91dCh0aW1lb3V0LCBydCpNYXRoLnBvdygyLCByZXRyaWVkKyspKTtcbiAgICAgICAgbWVzc2FnZTJLZXlbbWVzc2FnZV0gPSB7aWQ6IGlkLCBkZXN0OiBkZXN0fTtcbiAgICAgICAgcmVxdWVzdHMuc2V0KHJlcXVlc3QsIGlkLCBkZXN0KTtcblxuICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgZW5jb2RlX3RyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gcmV0cnkodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAgIGNvbnNvbGUud2FybihyZXRyaWVkKycgcmV0cnkgZm9yIHJlcXVlc3QgbWVzc2FnZTonLG1lc3NhZ2UpO1xuXG4gICAgICAgIHZhciB0aW1lb3V0ID0gcHJvY2Vzc2VkUmVzcG9uc2VzLnBvcChpZCwgZGVzdCk7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblxuICAgICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHRpbWVvdXQoKVxuICAgICAge1xuICAgICAgICBpZihyZXRyaWVkIDwgbWF4X3JldHJpZXMpXG4gICAgICAgICAgcmV0dXJuIHJldHJ5KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSZXF1ZXN0IGhhcyB0aW1lZCBvdXQnKTtcbiAgICAgICAgICAgIGVycm9yLnJlcXVlc3QgPSBtZXNzYWdlO1xuXG4gICAgICAgIGVycm9yLnJldHJ5ID0gcmV0cnk7XG5cbiAgICAgICAgZGlzcGF0Y2hDYWxsYmFjayhlcnJvcilcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgIH07XG5cbiAgICAvLyBSZXR1cm4gdGhlIHBhY2tlZCBtZXNzYWdlXG4gICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UpO1xuXG4gICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0KVxuICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIERlY29kZSBhbmQgcHJvY2VzcyBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgbWVzc2FnZVxuICAgKlxuICAgKiBAcmV0dXJucyB7UnBjTm90aWZpY2F0aW9ufFJwY1JlcXVlc3R8dW5kZWZpbmVkfSAtIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICogICBub3RpZmljYXRpb24gb3IgdGhlIHJlcXVlc3QuIElmIGEgcmVzcG9uc2Ugd2FzIHByb2Nlc3NlZCwgaXQgd2lsbCByZXR1cm5cbiAgICogICBgdW5kZWZpbmVkYCB0byBub3RpZnkgdGhhdCBpdCB3YXMgcHJvY2Vzc2VkXG4gICAqXG4gICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXG4gICAqL1xuICB0aGlzLmRlY29kZSA9IGZ1bmN0aW9uKG1lc3NhZ2UsIHRyYW5zcG9ydClcbiAge1xuICAgIGlmKCFtZXNzYWdlKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk1lc3NhZ2UgaXMgbm90IGRlZmluZWRcIik7XG5cbiAgICB0cnlcbiAgICB7XG4gICAgICBtZXNzYWdlID0gcGFja2VyLnVucGFjayhtZXNzYWdlKTtcbiAgICB9XG4gICAgY2F0Y2goZSlcbiAgICB7XG4gICAgICAvLyBJZ25vcmUgaW52YWxpZCBtZXNzYWdlc1xuICAgICAgcmV0dXJuIGNvbnNvbGUuZGVidWcoZSwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHZhciBpZCAgICAgPSBtZXNzYWdlLmlkO1xuICAgIHZhciBhY2sgICAgPSBtZXNzYWdlLmFjaztcbiAgICB2YXIgbWV0aG9kID0gbWVzc2FnZS5tZXRob2Q7XG4gICAgdmFyIHBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zIHx8IHt9O1xuXG4gICAgdmFyIGZyb20gPSBwYXJhbXMuZnJvbTtcbiAgICB2YXIgZGVzdCA9IHBhcmFtcy5kZXN0O1xuXG4gICAgLy8gSWdub3JlIG1lc3NhZ2VzIHNlbmQgYnkgdXNcbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQgJiYgZnJvbSA9PSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gTm90aWZpY2F0aW9uXG4gICAgaWYoaWQgPT0gdW5kZWZpbmVkICYmIGFjayA9PSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IG5ldyBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCBub3RpZmljYXRpb24pKSByZXR1cm47XG4gICAgICByZXR1cm4gbm90aWZpY2F0aW9uO1xuICAgIH07XG5cblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXF1ZXN0KClcbiAgICB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIGEgdHJhbnNwb3J0IGFuZCBpdCdzIGEgZHVwbGljYXRlZCByZXF1ZXN0LCByZXBseSBpbm1lZGlhdGx5XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpIHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuICAgICAgICBpZihyZXNwb25zZSlcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQocmVzcG9uc2UubWVzc2FnZSk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgaWRBY2sgPSAoaWQgIT0gdW5kZWZpbmVkKSA/IGlkIDogYWNrO1xuICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWRBY2ssIGZyb20sIHRyYW5zcG9ydCk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIHJlcXVlc3QpKSByZXR1cm47XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIGVycm9yLCByZXN1bHQpXG4gICAge1xuICAgICAgcmVxdWVzdC5jYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gZHVwbGljYXRlZFJlc3BvbnNlKHRpbWVvdXQpXG4gICAge1xuICAgICAgY29uc29sZS53YXJuKFwiUmVzcG9uc2UgYWxyZWFkeSBwcm9jZXNzZWRcIiwgbWVzc2FnZSk7XG5cbiAgICAgIC8vIFVwZGF0ZSBkdXBsaWNhdGVkIHJlc3BvbnNlcyB0aW1lb3V0XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSk7XG4gICAgfTtcblxuXG4gICAgLy8gUmVxdWVzdCwgb3IgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgaWYobWV0aG9kKVxuICAgIHtcbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICAgIGlmKGRlc3QgPT0gdW5kZWZpbmVkIHx8IGRlc3QgPT0gc2VsZi5wZWVySUQpXG4gICAgICB7XG4gICAgICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHJlcXVlc3QpXG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgcmVzcG9uc2VNZXRob2RzID0gcmVxdWVzdC5yZXNwb25zZU1ldGhvZHM7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLmVycm9yKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBwYXJhbXMpO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5yZXNwb25zZSlcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgbnVsbCwgcGFyYW1zKTtcblxuICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocHJvY2Vzc2VkKVxuICAgICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVxdWVzdFxuICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgfTtcblxuICAgIHZhciBlcnJvciAgPSBtZXNzYWdlLmVycm9yO1xuICAgIHZhciByZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcblxuICAgIC8vIElnbm9yZSByZXNwb25zZXMgbm90IHNlbmQgdG8gdXNcbiAgICBpZihlcnJvciAgJiYgZXJyb3IuZGVzdCAgJiYgZXJyb3IuZGVzdCAgIT0gc2VsZi5wZWVySUQpIHJldHVybjtcbiAgICBpZihyZXN1bHQgJiYgcmVzdWx0LmRlc3QgJiYgcmVzdWx0LmRlc3QgIT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIFJlc3BvbnNlXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICBpZighcmVxdWVzdClcbiAgICB7XG4gICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgaWYocHJvY2Vzc2VkKVxuICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG5cbiAgICAgIHJldHVybiBjb25zb2xlLndhcm4oXCJObyBjYWxsYmFjayB3YXMgZGVmaW5lZCBmb3IgdGhpcyBtZXNzYWdlXCIsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICAvLyBQcm9jZXNzIHJlc3BvbnNlXG4gICAgcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIGVycm9yLCByZXN1bHQpO1xuICB9O1xufTtcbmluaGVyaXRzKFJwY0J1aWxkZXIsIEV2ZW50RW1pdHRlcik7XG5cblxuUnBjQnVpbGRlci5ScGNOb3RpZmljYXRpb24gPSBScGNOb3RpZmljYXRpb247XG5cblxubW9kdWxlLmV4cG9ydHMgPSBScGNCdWlsZGVyO1xuXG52YXIgY2xpZW50cyA9IHJlcXVpcmUoJy4vY2xpZW50cycpO1xudmFyIHRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL2NsaWVudHMvdHJhbnNwb3J0cycpO1xuXG5ScGNCdWlsZGVyLmNsaWVudHMgPSBjbGllbnRzO1xuUnBjQnVpbGRlci5jbGllbnRzLnRyYW5zcG9ydHMgPSB0cmFuc3BvcnRzO1xuUnBjQnVpbGRlci5wYWNrZXJzID0gcGFja2VycztcbiIsIi8qKlxuICogSnNvblJQQyAyLjAgcGFja2VyXG4gKi9cblxuLyoqXG4gKiBQYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBtZXNzYWdlIC0gb2JqZWN0IHRvIGJlIHBhY2thZ2VkLiBJdCByZXF1aXJlcyB0byBoYXZlIGFsbCB0aGVcbiAqICAgZmllbGRzIG5lZWRlZCBieSB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZSB0aGF0IGl0J3MgZ29pbmcgdG8gYmUgZ2VuZXJhdGVkXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSAtIHRoZSBzdHJpbmdpZmllZCBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHBhY2sobWVzc2FnZSwgaWQpXG57XG4gIHZhciByZXN1bHQgPVxuICB7XG4gICAganNvbnJwYzogXCIyLjBcIlxuICB9O1xuXG4gIC8vIFJlcXVlc3RcbiAgaWYobWVzc2FnZS5tZXRob2QpXG4gIHtcbiAgICByZXN1bHQubWV0aG9kID0gbWVzc2FnZS5tZXRob2Q7XG5cbiAgICBpZihtZXNzYWdlLnBhcmFtcylcbiAgICAgIHJlc3VsdC5wYXJhbXMgPSBtZXNzYWdlLnBhcmFtcztcblxuICAgIC8vIFJlcXVlc3QgaXMgYSBub3RpZmljYXRpb25cbiAgICBpZihpZCAhPSB1bmRlZmluZWQpXG4gICAgICByZXN1bHQuaWQgPSBpZDtcbiAgfVxuXG4gIC8vIFJlc3BvbnNlXG4gIGVsc2UgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICB7XG4gICAgaWYobWVzc2FnZS5lcnJvcilcbiAgICB7XG4gICAgICBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkXCIpO1xuXG4gICAgICByZXN1bHQuZXJyb3IgPSBtZXNzYWdlLmVycm9yO1xuICAgIH1cbiAgICBlbHNlIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICByZXN1bHQucmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkXCIpO1xuXG4gICAgcmVzdWx0LmlkID0gaWQ7XG4gIH07XG5cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHJlc3VsdCk7XG59O1xuXG4vKipcbiAqIFVucGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHRocm93cyB7VHlwZUVycm9yfSAtIEludmFsaWQgSnNvblJQQyB2ZXJzaW9uXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSAtIG9iamVjdCBmaWxsZWQgd2l0aCB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZSBjb250ZW50XG4gKi9cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB2YXIgcmVzdWx0ID0gbWVzc2FnZTtcblxuICBpZih0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgfHwgbWVzc2FnZSBpbnN0YW5jZW9mIFN0cmluZykge1xuICAgIHJlc3VsdCA9IEpTT04ucGFyc2UobWVzc2FnZSk7XG4gIH1cblxuICAvLyBDaGVjayBpZiBpdCdzIGEgdmFsaWQgbWVzc2FnZVxuXG4gIHZhciB2ZXJzaW9uID0gcmVzdWx0Lmpzb25ycGM7XG4gIGlmKHZlcnNpb24gIT09ICcyLjAnKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIEpzb25SUEMgdmVyc2lvbiAnXCIgKyB2ZXJzaW9uICsgXCInOiBcIiArIG1lc3NhZ2UpO1xuXG4gIC8vIFJlc3BvbnNlXG4gIGlmKHJlc3VsdC5tZXRob2QgPT0gdW5kZWZpbmVkKVxuICB7XG4gICAgaWYocmVzdWx0LmlkID09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIG1lc3NhZ2U6IFwiK21lc3NhZ2UpO1xuXG4gICAgdmFyIHJlc3VsdF9kZWZpbmVkID0gcmVzdWx0LnJlc3VsdCAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBlcnJvcl9kZWZpbmVkICA9IHJlc3VsdC5lcnJvciAgIT09IHVuZGVmaW5lZDtcblxuICAgIC8vIENoZWNrIG9ubHkgcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQsIG5vdCBib3RoIG9yIG5vbmVcbiAgICBpZihyZXN1bHRfZGVmaW5lZCAmJiBlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICBpZighcmVzdWx0X2RlZmluZWQgJiYgIWVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgcmVzdWx0LmFjayA9IHJlc3VsdC5pZDtcbiAgICBkZWxldGUgcmVzdWx0LmlkO1xuICB9XG5cbiAgLy8gUmV0dXJuIHVucGFja2VkIG1lc3NhZ2VcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJmdW5jdGlvbiBwYWNrKG1lc3NhZ2UpXG57XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJOb3QgeWV0IGltcGxlbWVudGVkXCIpO1xufTtcblxuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJOb3QgeWV0IGltcGxlbWVudGVkXCIpO1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsInZhciBKc29uUlBDID0gcmVxdWlyZSgnLi9Kc29uUlBDJyk7XG52YXIgWG1sUlBDICA9IHJlcXVpcmUoJy4vWG1sUlBDJyk7XG5cblxuZXhwb3J0cy5Kc29uUlBDID0gSnNvblJQQztcbmV4cG9ydHMuWG1sUlBDICA9IFhtbFJQQztcbiIsIi8vIExhc3QgdGltZSB1cGRhdGVkIG9uIEp1bmUgMDgsIDIwMThcblxuLy8gTGF0ZXN0IGZpbGUgY2FuIGJlIGZvdW5kIGhlcmU6IGh0dHBzOi8vY2RuLndlYnJ0Yy1leHBlcmltZW50LmNvbS9nZXRTY3JlZW5JZC5qc1xuXG4vLyBNdWF6IEtoYW4gICAgICAgICAtIHd3dy5NdWF6S2hhbi5jb21cbi8vIE1JVCBMaWNlbnNlICAgICAgIC0gd3d3LldlYlJUQy1FeHBlcmltZW50LmNvbS9saWNlbmNlXG4vLyBEb2N1bWVudGF0aW9uICAgICAtIGh0dHBzOi8vZ2l0aHViLmNvbS9tdWF6LWtoYW4vZ2V0U2NyZWVuSWQuXG5cbi8vIF9fX19fX19fX19fX19fXG4vLyBnZXRTY3JlZW5JZC5qc1xuXG4vKlxuZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgLy8gZXJyb3IgICAgPT0gbnVsbCB8fCAncGVybWlzc2lvbi1kZW5pZWQnIHx8ICdub3QtaW5zdGFsbGVkJyB8fCAnaW5zdGFsbGVkLWRpc2FibGVkJyB8fCAnbm90LWNocm9tZSdcbiAgICAvLyBzb3VyY2VJZCA9PSBudWxsIHx8ICdzdHJpbmcnIHx8ICdmaXJlZm94J1xuICAgIFxuICAgIGlmKG1pY3Jvc29mdEVkZ2UpIHtcbiAgICAgICAgbmF2aWdhdG9yLmdldERpc3BsYXlNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzLCBvbkZhaWx1cmUpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2VzcyljYXRjaChvbkZhaWx1cmUpO1xuICAgIH1cbn0sICdwYXNzIHNlY29uZCBwYXJhbWV0ZXIgb25seSBpZiB5b3Ugd2FudCBzeXN0ZW0gYXVkaW8nKTtcbiovXG5cbndpbmRvdy5nZXRTY3JlZW5JZCA9IGZ1bmN0aW9uIChmaXJlZm94U3RyaW5nLCBjYWxsYmFjaywgY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0VkZ2UnKSAhPT0gLTEgJiYgKCEhbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IgfHwgISFuYXZpZ2F0b3IubXNTYXZlQmxvYikpIHtcbiAgICAgICAgLy8gbWljcm9zb2Z0IGVkZ2UgPT4gbmF2aWdhdG9yLmdldERpc3BsYXlNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzLCBvbkZhaWx1cmUpO1xuICAgICAgICBjYWxsYmFjayh7XG4gICAgICAgICAgICB2aWRlbzogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIC8vIHNvdXJjZUlkID09ICdmaXJlZm94J1xuICAgIC8vIHNjcmVlbl9jb25zdHJhaW50cyA9IHsuLi59XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjayhudWxsLCAnZmlyZWZveCcsIHtcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgbW96TWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmcsXG4gICAgICAgICAgICAgICAgbWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdwZXJtaXNzaW9uLWRlbmllZCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGdldFNjcmVlbkNvbnN0cmFpbnRzKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZXZlbnQuZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjaykpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cywgbnVsbCwgZ2V0U2NyZWVuQ29uc3RyYWludHMoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY3VzdG9tX3BhcmFtZXRlcikge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UsIDEwMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoZXJyb3IsIHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgIHZhciBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgIGF1ZGlvOiBmYWxzZSxcbiAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIG1heFdpZHRoOiB3aW5kb3cuc2NyZWVuLndpZHRoID4gMTkyMCA/IHdpbmRvdy5zY3JlZW4ud2lkdGggOiAxOTIwLFxuICAgICAgICAgICAgICAgIG1heEhlaWdodDogd2luZG93LnNjcmVlbi5oZWlnaHQgPiAxMDgwID8gd2luZG93LnNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCEhY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvID0ge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgLy8gZWNob0NhbmNlbGxhdGlvbjogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChzb3VyY2VJZCkge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMudmlkZW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICBpZiAoc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvICYmIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpby5tYW5kYXRvcnkpIHtcbiAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjcmVlbl9jb25zdHJhaW50cztcbn1cblxuZnVuY3Rpb24gcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghY3VzdG9tX3BhcmFtZXRlcikge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlU291cmNlSWQ6IHRydWVcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoISFjdXN0b21fcGFyYW1ldGVyLmZvckVhY2gpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZUN1c3RvbVNvdXJjZUlkOiBjdXN0b21fcGFyYW1ldGVyXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW86IHRydWVcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG59XG5cbnZhciBpZnJhbWU7XG5cbi8vIHRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBSVENNdWx0aUNvbm5lY3Rpb24gdjNcbndpbmRvdy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICBnZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgIGlmICghc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdHJ1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yLCBzY3JlZW5fY29uc3RyYWludHMudmlkZW8pO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cbmZ1bmN0aW9uIGxvYWRJRnJhbWUobG9hZENhbGxiYWNrKSB7XG4gICAgaWYgKGlmcmFtZSkge1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIGlmcmFtZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmcmFtZS5pc0xvYWRlZCA9IHRydWU7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgIH07XG4gICAgaWZyYW1lLnNyYyA9ICdodHRwczovL29wZW52aWR1LmdpdGh1Yi5pby9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uLyc7XG4gICAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgKGRvY3VtZW50LmJvZHkgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5hcHBlbmRDaGlsZChpZnJhbWUpO1xufVxuXG53aW5kb3cuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0VGltZW91dChwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSwgMTAwKTtcbn07XG5cbmZ1bmN0aW9uIHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKCkge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSwgMTAwKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzOiB0cnVlXG4gICAgfSwgJyonKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5JZCA9IGdldFNjcmVlbklkOyIsIi8vIGdsb2JhbCB2YXJpYWJsZXNcbnZhciBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xudmFyIHNvdXJjZUlkO1xudmFyIHNjcmVlbkNhbGxiYWNrO1xudmFyIGlzRmlyZWZveCA9IHR5cGVvZiB3aW5kb3cuSW5zdGFsbFRyaWdnZXIgIT09ICd1bmRlZmluZWQnO1xudmFyIGlzT3BlcmEgPSAhIXdpbmRvdy5vcGVyYSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJyBPUFIvJykgPj0gMDtcbnZhciBpc0Nocm9tZSA9ICEhd2luZG93LmNocm9tZSAmJiAhaXNPcGVyYTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQub3JpZ2luICE9IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBvbk1lc3NhZ2VDYWxsYmFjayhldmVudC5kYXRhKTtcbn0pO1xuXG4vLyBhbmQgdGhlIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyByZWNlaXZlZCBtZXNzYWdlc1xuZnVuY3Rpb24gb25NZXNzYWdlQ2FsbGJhY2soZGF0YSkge1xuICAgIC8vIFwiY2FuY2VsXCIgYnV0dG9uIGlzIGNsaWNrZWRcbiAgICBpZiAoZGF0YSA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICBpZiAoc2NyZWVuQ2FsbGJhY2spXG4gICAgICAgICAgICByZXR1cm4gc2NyZWVuQ2FsbGJhY2soJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gbm90aWZpZWQgaGlzIHByZXNlbmNlXG4gICAgaWYgKGRhdGEgPT0gJ3J0Y211bHRpY29ubmVjdGlvbi1leHRlbnNpb24tbG9hZGVkJykge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdkZXNrdG9wJztcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIHNoYXJlZCB0ZW1wIHNvdXJjZUlkXG4gICAgaWYgKGRhdGEuc291cmNlSWQgJiYgc2NyZWVuQ2FsbGJhY2spIHtcbiAgICAgICAgc2NyZWVuQ2FsbGJhY2soc291cmNlSWQgPSBkYXRhLnNvdXJjZUlkLCBkYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrID09PSB0cnVlKTtcbiAgICB9XG59XG5cbi8vIHRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIGNocm9tZSBleHRlbnNpb24gaXMgaW5zdGFsbGVkICYgZW5hYmxlZC5cbmZ1bmN0aW9uIGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgcmV0dXJuO1xuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHJldHVybiBjYWxsYmFjayh0cnVlKTtcblxuICAgIC8vIGFzayBleHRlbnNpb24gaWYgaXQgaXMgYXZhaWxhYmxlXG4gICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhmYWxzZSk7XG4gICAgICAgIH0gZWxzZSBjYWxsYmFjayh0cnVlKTtcbiAgICB9LCAyMDAwKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaylcbiAgICAgICAgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKCdnZXQtc291cmNlSWQnLCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0Q3VzdG9tU291cmNlSWQoYXJyLCBjYWxsYmFjaykge1xuICAgIGlmICghYXJyIHx8ICFhcnIuZm9yRWFjaCkgdGhyb3cgJ1wiYXJyXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeSBhbmQgaXQgbXVzdCBiZSBhbiBhcnJheS4nO1xuICAgIGlmICghY2FsbGJhY2spIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuXG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAnZ2V0LWN1c3RvbS1zb3VyY2VJZCc6IGFyclxuICAgIH0sICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZFdpdGhBdWRpbyhjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKCdhdWRpby1wbHVzLXRhYicsICcqJyk7XG59XG5cbmZ1bmN0aW9uIGdldENocm9tZUV4dGVuc2lvblN0YXR1cyhleHRlbnNpb25pZCwgY2FsbGJhY2spIHtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soJ25vdC1jaHJvbWUnKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB7XG4gICAgICAgIGNhbGxiYWNrID0gZXh0ZW5zaW9uaWQ7XG4gICAgICAgIGV4dGVuc2lvbmlkID0gJ2xmY2dmZXBhZm5vYmRsb2VjY2huZmFjbGliZW5qb2xkJzsgLy8gZGVmYXVsdCBleHRlbnNpb24taWRcbiAgICB9XG4gICAgdmFyIGltYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG4gICAgaW1hZ2Uuc3JjID0gJ2Nocm9tZS1leHRlbnNpb246Ly8nICsgZXh0ZW5zaW9uaWQgKyAnL2ljb24ucG5nJztcbiAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG4gICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1kaXNhYmxlZCcpO1xuICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIH0sIDIwMDApO1xuICAgIH07XG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2FsbGJhY2soJ25vdC1pbnN0YWxsZWQnKTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyhjYWxsYmFjaykge1xuICAgIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCB0cnVlKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBleHBsYWlucyBob3cgdG8gdXNlIGFib3ZlIG1ldGhvZHMvb2JqZWN0c1xuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgIHNvdXJjZUlkID0gJyc7XG4gICAgdmFyIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyA9IHtcbiAgICAgICAgbW96TWVkaWFTb3VyY2U6ICd3aW5kb3cnLFxuICAgICAgICBtZWRpYVNvdXJjZTogJ3dpbmRvdydcbiAgICB9O1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMpO1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IGRlZmluZXMgZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzXG4gICAgLy8gdGhhdCB3aWxsIGJlIHVzZWQgdG8gY2FwdHVyZSBjb250ZW50IG9mIHNjcmVlblxuICAgIHZhciBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGNocm9tZU1lZGlhU291cmNlLFxuICAgICAgICAgICAgbWF4V2lkdGg6IHNjcmVlbi53aWR0aCA+IDE5MjAgPyBzY3JlZW4ud2lkdGggOiAxOTIwLFxuICAgICAgICAgICAgbWF4SGVpZ2h0OiBzY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbmFsOiBbXVxuICAgIH07XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgdmVyaWZpZXMgY2hyb21lIGV4dGVuc2lvbiBhdmFpbGFiaWxpdHlcbiAgICAvLyBpZiBpbnN0YWxsZWQgYW5kIGF2YWlsYWJsZSB0aGVuIGl0IHdpbGwgaW52b2tlIGV4dGVuc2lvbiBBUElcbiAgICAvLyBvdGhlcndpc2UgaXQgd2lsbCBmYWxsYmFjayB0byBjb21tYW5kLWxpbmUgYmFzZWQgc2NyZWVuIGNhcHR1cmluZyBBUElcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnICYmICFzb3VyY2VJZCkge1xuICAgICAgICBpZiAoY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZFdpdGhBdWRpbyhmdW5jdGlvbiAoc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmNhblJlcXVlc3RBdWRpb1RyYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkKGZ1bmN0aW9uIChzb3VyY2VJZCkge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRoaXMgc3RhdGVtZW50IHNldHMgZ2V0cyAnc291cmNlSWRcIiBhbmQgc2V0cyBcImNocm9tZU1lZGlhU291cmNlSWRcIiBcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuICAgIH1cblxuICAgIC8vIG5vdyBpbnZva2luZyBuYXRpdmUgZ2V0VXNlck1lZGlhIEFQSVxuICAgIGNhbGxiYWNrKG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBnZXRTY3JlZW5Db25zdHJhaW50cztcbmV4cG9ydHMuZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8gPSBnZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbztcbmV4cG9ydHMuaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUgPSBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZTtcbmV4cG9ydHMuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzID0gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzO1xuZXhwb3J0cy5nZXRTb3VyY2VJZCA9IGdldFNvdXJjZUlkOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IGZyZWVpY2UgPSByZXF1aXJlKCdmcmVlaWNlJyk7XG5pbXBvcnQgdXVpZCA9IHJlcXVpcmUoJ3V1aWQnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24ge1xuICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgYXVkaW86IGJvb2xlYW4sXG4gICAgICAgIHZpZGVvOiBib29sZWFuXG4gICAgfTtcbiAgICBzaW11bGNhc3Q6IGJvb2xlYW47XG4gICAgb25pY2VjYW5kaWRhdGU6IChldmVudCkgPT4gdm9pZDtcbiAgICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZDtcbiAgICBtZWRpYVN0cmVhbT86IE1lZGlhU3RyZWFtO1xuICAgIG1vZGU/OiAnc2VuZG9ubHknIHwgJ3JlY3Zvbmx5JyB8ICdzZW5kcmVjdic7XG4gICAgaWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyIHtcblxuICAgIHBjOiBSVENQZWVyQ29ubmVjdGlvbjtcbiAgICBpZDogc3RyaW5nO1xuICAgIHJlbW90ZUNhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcbiAgICBsb2NhbENhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIGljZUNhbmRpZGF0ZUxpc3Q6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBwcml2YXRlIGNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPSAoISF0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycy5sZW5ndGggPiAwKSA/IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIDogZnJlZWljZSgpO1xuXG4gICAgICAgIHRoaXMucGMgPSBuZXcgUlRDUGVlckNvbm5lY3Rpb24oeyBpY2VTZXJ2ZXJzOiB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyB9KTtcbiAgICAgICAgdGhpcy5pZCA9ICEhY29uZmlndXJhdGlvbi5pZCA/IGNvbmZpZ3VyYXRpb24uaWQgOiB1dWlkLnY0KCk7XG5cbiAgICAgICAgdGhpcy5wYy5vbmljZWNhbmRpZGF0ZSA9IGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmICghIWV2ZW50LmNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0gZXZlbnQuY2FuZGlkYXRlO1xuICAgICAgICAgICAgICAgIGlmIChjYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZS5wdXNoKDxSVENJY2VDYW5kaWRhdGU+eyBjYW5kaWRhdGU6IGNhbmRpZGF0ZS5jYW5kaWRhdGUgfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ub25pY2VjYW5kaWRhdGUoZXZlbnQuY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5wYy5vbnNpZ25hbGluZ3N0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdzdGFibGUnKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKDxSVENJY2VDYW5kaWRhdGU+dGhpcy5pY2VDYW5kaWRhdGVMaXN0LnNoaWZ0KCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBjcmVhdGVzIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBvYmplY3QgdGFraW5nIGludG8gYWNjb3VudCB0aGVcbiAgICAgKiBwcm9wZXJ0aWVzIHJlY2VpdmVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gSXQgc3RhcnRzIHRoZSBTRFAgbmVnb3RpYXRpb25cbiAgICAgKiBwcm9jZXNzOiBnZW5lcmF0ZXMgdGhlIFNEUCBvZmZlciBhbmQgaW52b2tlcyB0aGUgb25zZHBvZmZlciBjYWxsYmFjay4gVGhpc1xuICAgICAqIGNhbGxiYWNrIGlzIGV4cGVjdGVkIHRvIHNlbmQgdGhlIFNEUCBvZmZlciwgaW4gb3JkZXIgdG8gb2J0YWluIGFuIFNEUFxuICAgICAqIGFuc3dlciBmcm9tIGFub3RoZXIgcGVlci5cbiAgICAgKi9cbiAgICBzdGFydCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdUaGUgcGVlciBjb25uZWN0aW9uIG9iamVjdCBpcyBpbiBcImNsb3NlZFwiIHN0YXRlLiBUaGlzIGlzIG1vc3QgbGlrZWx5IGR1ZSB0byBhbiBpbnZvY2F0aW9uIG9mIHRoZSBkaXNwb3NlIG1ldGhvZCBiZWZvcmUgYWNjZXB0aW5nIGluIHRoZSBkaWFsb2d1ZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMyOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBwYzIuYWRkU3RyZWFtKHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCB0cmFjayBvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0uZ2V0VHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhY2sodHJhY2ssIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBmcmVlcyB0aGUgcmVzb3VyY2VzIHVzZWQgYnkgV2ViUnRjUGVlclxuICAgICAqL1xuICAgIGRpc3Bvc2UodmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2s6IGJvb2xlYW4pIHtcbiAgICAgICAgY29uc29sZS5kZWJ1ZygnRGlzcG9zaW5nIFdlYlJ0Y1BlZXInKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDYW5kaWRhdGVzUXVldWUgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlID0gW107XG5cbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnMgZGVwcmVjYXRlZFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VuZGVyIG9mIHBjMS5nZXRMb2NhbFN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+c2VuZGVyKS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBwYzEucmVtb3ZlU3RyZWFtKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnMgZGVwcmVjYXRlZFxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHBjMS5nZXRSZW1vdGVTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKDxNZWRpYVN0cmVhbT5yZWNlaXZlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VuZGVyIG9mIHRoaXMucGMuZ2V0U2VuZGVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhc2VuZGVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRlci50cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5yZW1vdmVUcmFjayhzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgdGhpcy5wYy5nZXRSZWNlaXZlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci50cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdFeGNlcHRpb24gZGlzcG9zaW5nIHdlYnJ0YyBwZWVyICcgKyBlcnIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIG9mZmVyLCBzZXRzIGl0IGFzIGxvY2FsIGRlc2NyaXB0aW9uIGFuZCByZXR1cm5zIHRoZSBvZmZlciBwYXJhbVxuICAgICAqIHRvIHNlbmQgdG8gT3BlblZpZHUgU2VydmVyICh3aWxsIGJlIHRoZSByZW1vdGUgZGVzY3JpcHRpb24gb2Ygb3RoZXIgcGVlcilcbiAgICAgKi9cbiAgICBnZW5lcmF0ZU9mZmVyKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgb2ZmZXJBdWRpbywgb2ZmZXJWaWRlbyA9IHRydWU7XG5cbiAgICAgICAgICAgIC8vIENvbnN0cmFpbnRzIG11c3QgaGF2ZSBib3RoIGJsb2Nrc1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBvZmZlckF1ZGlvID0gKHR5cGVvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ2Jvb2xlYW4nKSA/XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIDogdHJ1ZTtcbiAgICAgICAgICAgICAgICBvZmZlclZpZGVvID0gKHR5cGVvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA9PT0gJ2Jvb2xlYW4nKSA/XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvIDogdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29uc3RyYWludHM6IFJUQ09mZmVyT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZUF1ZGlvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJBdWRpbyksXG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyVmlkZW8pXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSVENQZWVyQ29ubmVjdGlvbiBjb25zdHJhaW50czogJyArIEpTT04uc3RyaW5naWZ5KGNvbnN0cmFpbnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJyAmJiBwbGF0Zm9ybS51YSEhLmluZGV4T2YoJ1NhZmFyaScpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSAoZXhjbHVkaW5nIElvbmljKSwgYXQgbGVhc3Qgb24gaU9TIGp1c3Qgc2VlbXMgdG8gc3VwcG9ydCB1bmlmaWVkIHBsYW4sIHdoZXJlYXMgaW4gb3RoZXIgYnJvd3NlcnMgaXMgbm90IHlldCByZWFkeSBhbmQgY29uc2lkZXJlZCBleHBlcmltZW50YWxcbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCdhdWRpbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChvZmZlclZpZGVvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ3ZpZGVvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWxvY2FsRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShsb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnTG9jYWwgZGVzY3JpcHRpb24gaXMgbm90IGRlZmluZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICB0aGlzLnBjLmNyZWF0ZU9mZmVyKGNvbnN0cmFpbnRzKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWxvY2FsRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShsb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnTG9jYWwgZGVzY3JpcHRpb24gaXMgbm90IGRlZmluZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiBpbnZva2VkIHdoZW4gYSBTRFAgYW5zd2VyIGlzIHJlY2VpdmVkLiBGaW5hbCBzdGVwIGluIFNEUCBuZWdvdGlhdGlvbiwgdGhlIHBlZXJcbiAgICAgKiBqdXN0IG5lZWRzIHRvIHNldCB0aGUgYW5zd2VyIGFzIGl0cyByZW1vdGUgZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICBwcm9jZXNzQW5zd2VyKHNkcEFuc3dlcjogc3RyaW5nLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fzd2VyICYmIHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltb3V0IGZvciBpT1MgZGV2aWNlJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayBmdW5jdGlvbiBpbnZva2VkIHdoZW4gYW4gSUNFIGNhbmRpZGF0ZSBpcyByZWNlaXZlZFxuICAgICAqL1xuICAgIGFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUmVtb3RlIElDRSBjYW5kaWRhdGUgcmVjZWl2ZWQnLCBpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDYW5kaWRhdGVzUXVldWUucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignUGVlckNvbm5lY3Rpb24gb2JqZWN0IGlzIGNsb3NlZCcpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnc3RhYmxlJzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5wYy5yZW1vdGVEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG59XG5cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJSZWN2b25seSBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdyZWN2b25seSc7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJTZW5kb25seSBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdzZW5kb25seSc7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJTZW5kcmVjdiBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdzZW5kcmVjdic7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8vIHRzbGludDpkaXNhYmxlOm5vLXN0cmluZy1saXRlcmFsXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgY2xhc3MgV2ViUnRjU3RhdHMge1xuXG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0VuYWJsZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzSW50ZXJ2YWxJZDogTm9kZUpTLlRpbWVyO1xuICAgIHByaXZhdGUgc3RhdHNJbnRlcnZhbCA9IDE7XG4gICAgcHJpdmF0ZSBzdGF0czogYW55ID0ge1xuICAgICAgICBpbmJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNEZWNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBvdXRib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRW5jb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0cmVhbTogU3RyZWFtKSB7IH1cblxuICAgIHB1YmxpYyBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2VsYXN0ZXN0LWluc3RydW1lbnRhdGlvbicpO1xuXG4gICAgICAgIGlmICghIWVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKSB7XG4gICAgICAgICAgICAvLyBFbGFzVGVzdCBpbnN0cnVtZW50YXRpb24gb2JqZWN0IGZvdW5kIGluIGxvY2FsIHN0b3JhZ2VcblxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgZW5hYmxlZCBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGluc3RydW1lbnRhdGlvbiA9IEpTT04ucGFyc2UoZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgdGhpcy5zdGF0c0ludGVydmFsID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5pbnRlcnZhbDsgIC8vIEludGVydmFsIGluIHNlY29uZHNcblxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdsb2NhbFN0b3JhZ2UgaXRlbTogJyArIEpTT04uc3RyaW5naWZ5KGluc3RydW1lbnRhdGlvbikpO1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB9LCB0aGlzLnN0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnV2ViUnRjIHN0YXRzIG5vdCBlbmFibGVkJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0b3BXZWJSdGNTdGF0cygpIHtcbiAgICAgICAgaWYgKHRoaXMud2ViUnRjU3RhdHNFbmFibGVkKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkKTtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIHN0b3BwZWQgZm9yIGRpc3Bvc2VkIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLFxuICAgICAgICAgICAgICAgIChzdGF0cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0Nocm9tZScpICE9PSAtMSkgfHwgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ09wZXJhJykgIT09IC0xKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxvY2FsQ2FuZGlkYXRlSWQsIHJlbW90ZUNhbmRpZGF0ZUlkLCBnb29nQ2FuZGlkYXRlUGFpcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsQ2FuZGlkYXRlcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVtb3RlQ2FuZGlkYXRlcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc3RhdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGF0ID0gc3RhdHNba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnbG9jYWxjYW5kaWRhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdyZW1vdGVjYW5kaWRhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAnZ29vZ0NhbmRpZGF0ZVBhaXInICYmIChzdGF0Lmdvb2dBY3RpdmVDb25uZWN0aW9uID09PSAndHJ1ZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dDYW5kaWRhdGVQYWlyID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVJZCA9IHN0YXQubG9jYWxDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlSWQgPSBzdGF0LnJlbW90ZUNhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbExvY2FsQ2FuZGlkYXRlID0gbG9jYWxDYW5kaWRhdGVzW2xvY2FsQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxMb2NhbENhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0TG9jYWxJY2VDYW5kaWRhdGVMaXN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZCA9IGNhbmRMaXN0LmZpbHRlcigoYzogUlRDSWNlQ2FuZGlkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoISFjLmNhbmRpZGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wcmlvcml0eSkgPj0gMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgbG9jYWwgY2FuZGlkYXRlIGluIGxpc3Qgb2Ygc2VudCBJQ0UgY2FuZGlkYXRlcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSBsb2NhbCBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSByZW1vdGVDYW5kaWRhdGVzW3JlbW90ZUNhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsUmVtb3RlQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZCA9IGNhbmRMaXN0LmZpbHRlcigoYzogUlRDSWNlQ2FuZGlkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoISFjLmNhbmRpZGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wcmlvcml0eSkgPj0gMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIHJlbW90ZSBjYW5kaWRhdGUgaW4gbGlzdCBvZiByZWNlaXZlZCBJQ0UgY2FuZGlkYXRlcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgcmVtb3RlIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dDYW5kaWRhdGVQYWlyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlOiBmaW5hbExvY2FsQ2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZTogZmluYWxSZW1vdGVDYW5kaWRhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdTZWxlY3RlZCBJQ0UgY2FuZGlkYXRlIGluZm8gb25seSBhdmFpbGFibGUgZm9yIENocm9tZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBzZW5kUG9zdCA9IChqc29uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBodHRwOiBYTUxIdHRwUmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgY29uc3QgdXJsOiBzdHJpbmcgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmh0dHBFbmRwb2ludDtcbiAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIHVybCwgdHJ1ZSk7XG5cbiAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcblxuICAgICAgICAgICAgaHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7IC8vIENhbGwgYSBmdW5jdGlvbiB3aGVuIHRoZSBzdGF0ZSBjaGFuZ2VzLlxuICAgICAgICAgICAgICAgIGlmIChodHRwLnJlYWR5U3RhdGUgPT09IDQgJiYgaHR0cC5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnV2ViUnRjIHN0YXRzIHN1Y2Nlc3NmdWxseSBzZW50IHRvICcgKyB1cmwgKyAnIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0dHAuc2VuZChqc29uKTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmID0gKHN0YXRzKSA9PiB7XG5cbiAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgc3RhdHMuZm9yRWFjaCgoc3RhdCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBqc29uID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKChzdGF0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBvdXRib3VuZC1ydHAgc3RhdGlzdGljc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQubmFja0NvdW50ICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQucmVtb3RlSWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGppdCA9IHN0YXQuaml0dGVyICogMTAwMDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAoc3RhdC5ieXRlc1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IGppdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiAnbXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ25hY2tDb3VudCddID0gKHN0YXQubmFja0NvdW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWyduYWNrQ291bnQnXSA9ICdwYWNrZXRzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQgPSBzdGF0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcblxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChzdGF0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgaW5ib3VuZC1ydHAgc3RhdGlzdGljc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdvdXRib3VuZCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19vdXRib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAoc3RhdC5wYWNrZXRzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkID0gc3RhdC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNTZW50ID0gc3RhdC5wYWNrZXRzU2VudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0Nocm9tZScpICE9PSAtMSkgfHwgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ09wZXJhJykgIT09IC0xKSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0YXRzKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGF0ID0gc3RhdHNba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ3NzcmMnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBqc29uID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnYnl0ZXNSZWNlaXZlZCcgaW4gc3RhdCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAnYXVkaW8nICYmICdhdWRpb091dHB1dExldmVsJyBpbiBzdGF0KSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJyAmJiAncXBTdW0nIGluIHN0YXQpXG4gICAgICAgICAgICAgICAgICAgICAgICApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5ib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAoc3RhdC5ieXRlc1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBzdGF0Lmdvb2dKaXR0ZXJCdWZmZXJNcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiAnbXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ25hY2tDb3VudCddID0gKHN0YXQuZ29vZ05hY2tzU2VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWyduYWNrQ291bnQnXSA9ICdwYWNrZXRzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQuZ29vZ05hY2tzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQgPSBzdGF0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJ2J5dGVzU2VudCcgaW4gc3RhdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG91dGJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19vdXRib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAoc3RhdC5wYWNrZXRzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkID0gc3RhdC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNTZW50ID0gc3RhdC5wYWNrZXRzU2VudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSwgZiwgKGVycm9yKSA9PiB7IGNvbnNvbGUubG9nKGVycm9yKTsgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZSk7XG4gICAgICAgIGNvbnN0IHN0YW5kYXJkUmVwb3J0ID0ge307XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHJlc3BvbnNlKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2Vba2V5XSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3BvbnNlLnJlc3VsdCgpLmZvckVhY2gocmVwb3J0ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0YW5kYXJkU3RhdHMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IHJlcG9ydC5pZCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IHJlcG9ydC50aW1lc3RhbXAsXG4gICAgICAgICAgICAgICAgdHlwZTogcmVwb3J0LnR5cGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXBvcnQubmFtZXMoKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgc3RhbmRhcmRTdGF0c1tuYW1lXSA9IHJlcG9ydC5zdGF0KG5hbWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzdGFuZGFyZFJlcG9ydFtzdGFuZGFyZFN0YXRzLmlkXSA9IHN0YW5kYXJkU3RhdHM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBzdGFuZGFyZFJlcG9ydDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFN0YXRzQWdub3N0aWMocGMsIHN1Y2Nlc3NDYiwgZmFpbHVyZUNiKSB7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICAvLyBnZXRTdGF0cyB0YWtlcyBhcmdzIGluIGRpZmZlcmVudCBvcmRlciBpbiBDaHJvbWUgYW5kIEZpcmVmb3hcbiAgICAgICAgICAgIHJldHVybiBwYy5nZXRTdGF0cyhudWxsKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXBvcnQgPSB0aGlzLnN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2IocmVwb3J0KTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGZhaWx1cmVDYik7XG4gICAgICAgIH0gZWxzZSBpZiAoKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0Nocm9tZScpICE9PSAtMSkgfHwgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ09wZXJhJykgIT09IC0xKSkge1xuICAgICAgICAgICAgLy8gSW4gQ2hyb21lLCB0aGUgZmlyc3QgdHdvIGFyZ3VtZW50cyBhcmUgcmV2ZXJzZWRcbiAgICAgICAgICAgIHJldHVybiBwYy5nZXRTdGF0cygocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXBvcnQgPSB0aGlzLnN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2IocmVwb3J0KTtcbiAgICAgICAgICAgIH0sIG51bGwsIGZhaWx1cmVDYik7XG4gICAgICAgIH1cbiAgICB9XG5cbn0iXX0= diff --git a/openvidu-electron/src/openvidu-browser-2.11.0.js b/openvidu-electron/src/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-electron/src/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-filters/web/index.html b/openvidu-filters/web/index.html index 3bab52002..c6a769a53 100644 --- a/openvidu-filters/web/index.html +++ b/openvidu-filters/web/index.html @@ -14,7 +14,7 @@ - + diff --git a/openvidu-filters/web/openvidu-browser-2.10.0.js b/openvidu-filters/web/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-filters/web/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-filters/web/openvidu-browser-2.11.0.js b/openvidu-filters/web/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-filters/web/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-getaroom/docker/Dockerfile b/openvidu-getaroom/docker/Dockerfile index da049dc28..8c5740a7e 100644 --- a/openvidu-getaroom/docker/Dockerfile +++ b/openvidu-getaroom/docker/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:16.04 LABEL maintainer="openvidu@gmail.com" # Install Kurento Media Server (KMS) -RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.10.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ +RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.11.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83 \ && apt-get update \ && apt-get -y install kurento-media-server \ diff --git a/openvidu-getaroom/web/index.html b/openvidu-getaroom/web/index.html index 0be4301b0..3d2a525d6 100644 --- a/openvidu-getaroom/web/index.html +++ b/openvidu-getaroom/web/index.html @@ -14,7 +14,7 @@ - + diff --git a/openvidu-getaroom/web/openvidu-browser-2.10.0.js b/openvidu-getaroom/web/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-getaroom/web/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-getaroom/web/openvidu-browser-2.11.0.js b/openvidu-getaroom/web/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-getaroom/web/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-hello-world/web/index.html b/openvidu-hello-world/web/index.html index 9d7139269..adebffeaa 100644 --- a/openvidu-hello-world/web/index.html +++ b/openvidu-hello-world/web/index.html @@ -5,7 +5,7 @@ - + diff --git a/openvidu-hello-world/web/openvidu-browser-2.10.0.js b/openvidu-hello-world/web/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-hello-world/web/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-hello-world/web/openvidu-browser-2.11.0.js b/openvidu-hello-world/web/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-hello-world/web/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0ZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlDQSxnREFBK0M7QUFFL0MsSUFBSSxNQUFNLEVBQUU7SUFDUixNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsbUJBQVEsQ0FBQztDQUNqQzs7Ozs7QUNjRCxtQ0FBa0M7QUFVbEM7SUF5Q0ksb0JBQW9CLE9BQWdCLEVBQUUsSUFBd0I7UUFBMUMsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQVZwQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBV2IsSUFBSSxHQUFHLEdBQUcsdUJBQXVCLENBQUM7UUFDbEMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO1lBRVIsR0FBRyxJQUFJLGdDQUFnQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1lBQ3hELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDbkMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzthQUM3QjtZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDZCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3hDO1NBQ0o7YUFBTTtZQUVILEdBQUcsSUFBSSxTQUFTLENBQUM7U0FDcEI7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFRRCxxQ0FBZ0IsR0FBaEIsVUFBaUIsU0FBMEI7UUFFdkMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLGVBQWU7WUFDbkYsSUFBSSxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVsQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEQsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQy9CLFNBQVMsRUFBRSxTQUFTLENBQUMsU0FBUztZQUM5QixNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDeEIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO1NBQ3pDLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtZQUNmLElBQUksS0FBSyxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsK0JBQStCO3NCQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDaEM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCxzQ0FBaUIsR0FBakIsVUFBa0IsT0FBOEI7UUFBaEQsaUJBd0JDO1FBcEJHLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQSxJQUFJO1lBQ2hCLElBQU0sYUFBYSxHQUF5QjtnQkFDeEMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsVUFBVSxFQUFFLEtBQUk7Z0JBQ2hCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM3QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7Z0JBQ3pCLGVBQWUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ3RGLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUzthQUNsRCxDQUFDO1lBQ0YsSUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztZQUV2RCxLQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLElBQUksQ0FBQywyQ0FBMkMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLDBEQUEwRCxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM5SyxDQUFDO0lBS0QsOEJBQVMsR0FBVCxVQUFVLE1BQWM7UUFDcEIsTUFBTSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDekIsQ0FBQztJQUtELGlDQUFZLEdBQVosVUFBYSxRQUFnQjtRQUN6QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUtELDRCQUFPLEdBQVA7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO1NBQ3RCO1FBQ0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVMLGlCQUFDO0FBQUQsQ0E1SUEsQUE0SUMsSUFBQTtBQTVJWSxnQ0FBVTs7Ozs7QUNUdkIsb0dBQW1HO0FBQ25HLHlFQUEyRjtBQVMzRjtJQTZDSSxnQkFBWSxJQUFZLEVBQUUsT0FBZTtRQVh6QyxhQUFRLEdBQXlDLEVBQUUsQ0FBQztRQVloRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUMzQixDQUFDO0lBU0QsMkJBQVUsR0FBVixVQUFXLE1BQWMsRUFBRSxNQUFjO1FBQXpDLGlCQXFDQztRQXBDRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFFLElBQUksWUFBWSxDQUFDO1lBQ2pCLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO2dCQUM1QixJQUFJO29CQUNBLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUN6QztnQkFBQyxPQUFPLEtBQUssRUFBRTtvQkFDWixJQUFNLFFBQVEsR0FBRyxtREFBbUQsQ0FBQztvQkFDckUsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDeEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUNwQjthQUNKO2lCQUFNO2dCQUNILFlBQVksR0FBVyxNQUFNLENBQUM7YUFDakM7WUFDRCxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNwQyxrQkFBa0IsRUFDbEIsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUNoRSxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkNBQTJDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3pGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUsdURBQXVELENBQUMsQ0FBQyxDQUFDO3FCQUNwSTt5QkFBTTt3QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdEYsSUFBTSxRQUFRLEdBQVMsTUFBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDOUQsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztvQkFDakYsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZMLEtBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNuTSxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBV0QsaUNBQWdCLEdBQWhCLFVBQWlCLFNBQWlCLEVBQUUsT0FBcUM7UUFBekUsaUJBc0JDO1FBckJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxHQUFHLFNBQVMsR0FBRyxhQUFhLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRyxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNwQyx3QkFBd0IsRUFDeEIsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsU0FBUyxXQUFBLEVBQUUsRUFDN0MsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLEtBQUssRUFBRTtvQkFDUCxPQUFPLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxHQUFHLFNBQVMsR0FBRyxhQUFhLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3hILElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUsMkRBQTJELENBQUMsQ0FBQyxDQUFDO3FCQUN4STt5QkFBTTt3QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO3FCQUFNO29CQUNILEtBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsT0FBTyxDQUFDO29CQUNuQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLFNBQVMsR0FBRyxrQ0FBa0MsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN4SCxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBVUQsb0NBQW1CLEdBQW5CLFVBQW9CLFNBQWlCO1FBQXJDLGlCQXNCQztRQXJCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDNUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDcEMsMkJBQTJCLEVBQzNCLEVBQUUsUUFBUSxFQUFFLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsV0FBQSxFQUFFLEVBQzdDLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxLQUFLLEVBQUU7b0JBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMxSCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUFFO3dCQUNwQixNQUFNLENBQUMsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDBCQUEwQixFQUFFLDJEQUEyRCxDQUFDLENBQUMsQ0FBQztxQkFDeEk7eUJBQU07d0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUNqQjtpQkFDSjtxQkFBTTtvQkFDSCxPQUFPLEtBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ2hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsU0FBUyxHQUFHLGtDQUFrQyxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3hILE9BQU8sRUFBRSxDQUFDO2lCQUNiO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTCxhQUFDO0FBQUQsQ0FqS0EsQUFpS0MsSUFBQTtBQWpLWSx3QkFBTTs7Ozs7QUNYbkIsbUZBQWtGO0FBQ2xGLG1DQUFzQztBQWdCdEM7SUFlSSx1QkFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFUMUIsV0FBTSxHQUFVLEVBQUUsQ0FBQztRQVV2QixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUM7UUFDNUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxjQUFjLENBQUM7UUFDMUUsSUFBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQU9ELDhCQUFNLEdBQU47UUFBQSxpQkFxRUM7UUFwRUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRS9CLElBQUk7Z0JBRUEsSUFBSSxPQUFPLGFBQWEsS0FBSyxXQUFXLEVBQUU7b0JBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkdBQTZHLENBQUMsQ0FBQztvQkFDN0gsTUFBTSxDQUFDLEtBQUssQ0FBQyw2R0FBNkcsQ0FBQyxDQUFDLENBQUM7aUJBQ2hJO2dCQUNELElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxLQUFLLEVBQUU7b0JBQ3pDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUZBQXlGLEdBQUcsS0FBSSxDQUFDLEtBQUssR0FBRyx3RUFBd0UsQ0FBQyxDQUFDLENBQUM7aUJBQ3BNO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsbUJBQW1CLEdBQUcsS0FBSSxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsQ0FBQztnQkFHM0gsSUFBSSxPQUFPLGFBQWEsQ0FBQyxlQUFlLEtBQUssVUFBVSxFQUFFO29CQUNyRCxJQUFJLE9BQU8sU0FBQSxDQUFDO29CQUNaLElBQUksYUFBYSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFO3dCQUN4RCxPQUFPLEdBQUcsRUFBRSxRQUFRLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQztxQkFDbkQ7eUJBQU0sSUFBSSxhQUFhLENBQUMsZUFBZSxDQUFDLHdCQUF3QixDQUFDLEVBQUU7d0JBQ2hFLE9BQU8sR0FBRyxFQUFFLFFBQVEsRUFBRSx3QkFBd0IsRUFBRSxDQUFDO3FCQUNwRDt5QkFBTSxJQUFJLGFBQWEsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQUMsRUFBRTt3QkFDL0QsT0FBTyxHQUFHLEVBQUUsUUFBUSxFQUFFLHVCQUF1QixFQUFFLENBQUM7cUJBQ25EO29CQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUNsRCxLQUFJLENBQUMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7aUJBQ2pGO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsb0VBQW9FLENBQUMsQ0FBQztvQkFDbkYsS0FBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7aUJBQ3hFO2dCQUVELEtBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBRWhDO1lBQUMsT0FBTyxHQUFHLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2Y7WUFFRCxLQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsR0FBRyxVQUFDLENBQUM7Z0JBQ25DLEtBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRyxVQUFDLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUMsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEdBQUc7Z0JBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0JBQStCLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDbEYsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUc7Z0JBQ3hCLEtBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRztnQkFDekIsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNqRixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsR0FBRztnQkFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNsRixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxVQUFDLENBQUM7Z0JBQzdCLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxTQUFTLENBQUM7WUFDMUMsT0FBTyxFQUFFLENBQUM7UUFFZCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFPRCw0QkFBSSxHQUFKO1FBQUEsaUJBZUM7UUFkRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSTtnQkFDQSxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsS0FBSyxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO29CQUN2RixNQUFNLENBQUMsS0FBSyxDQUFDLHlHQUF5RyxHQUFHLEtBQUksQ0FBQyxLQUFLLEdBQUcsNENBQTRDLENBQUMsQ0FBQyxDQUFDO2lCQUN4TDtnQkFDRCxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRztvQkFDeEIsS0FBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUNyQixPQUFPLEVBQUUsQ0FBQztnQkFDZCxDQUFDLENBQUM7Z0JBQ0YsS0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUM3QjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNiO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBT0QsNkJBQUssR0FBTDtRQUFBLGlCQVlDO1FBWEcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUk7Z0JBQ0EsSUFBSSxLQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsRUFBRTtvQkFDN0MsTUFBTSxDQUFDLEtBQUssQ0FBQyw0RkFBNEYsR0FBRyxLQUFJLENBQUMsS0FBSyxHQUFHLDBFQUEwRSxDQUFDLENBQUMsQ0FBQztpQkFDek07Z0JBQ0QsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDM0IsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxNQUFNLENBQUM7YUFDMUM7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDWixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDakI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFNRCw4QkFBTSxHQUFOO1FBQUEsaUJBWUM7UUFYRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSTtnQkFDQSxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsTUFBTSxFQUFFO29CQUMxQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBGQUEwRixHQUFHLEtBQUksQ0FBQyxLQUFLLEdBQUcsNENBQTRDLENBQUMsQ0FBQyxDQUFDO2lCQUN6SztnQkFDRCxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM1QixLQUFJLENBQUMsS0FBSyxHQUFHLHVDQUFrQixDQUFDLFNBQVMsQ0FBQzthQUM3QztZQUFDLE9BQU8sS0FBSyxFQUFFO2dCQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNqQjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU1ELCtCQUFPLEdBQVAsVUFBUSxhQUFhO1FBRWpCLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7WUFDNUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2RkFBNkYsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLDJDQUEyQyxDQUFDLENBQUMsQ0FBQztTQUMzSztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUVsQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQzVCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztTQUN6RDtRQUVELElBQUksT0FBTyxhQUFhLEtBQUssUUFBUSxFQUFFO1lBQ25DLElBQU0sZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRSxJQUFJLGdCQUFnQixFQUFFO2dCQUNsQixJQUFJLENBQUMsWUFBWSxHQUFHLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDdkU7U0FDSjthQUFNO1lBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNwRTtRQUVELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFFN0MsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLENBQUM7SUFNRCw2QkFBSyxHQUFMO1FBQUEsaUJBWUM7UUFYRyxJQUFNLENBQUMsR0FBRztZQUNOLE9BQU8sS0FBSSxDQUFDLElBQUksQ0FBQztZQUNqQixLQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNqQixPQUFPLEtBQUksQ0FBQyxhQUFhLENBQUM7WUFDMUIsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxLQUFLLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLE1BQU0sRUFBRTtZQUN6RixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQU0sT0FBQSxDQUFDLEVBQUUsRUFBSCxDQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsY0FBTSxPQUFBLENBQUMsRUFBRSxFQUFILENBQUcsQ0FBQyxDQUFDO1NBQ2hEO2FBQU07WUFDSCxDQUFDLEVBQUUsQ0FBQztTQUNQO0lBQ0wsQ0FBQztJQU1ELGdDQUFRLEdBQVI7UUFDSSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsOEZBQThGLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRywyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7U0FDNUs7YUFBTTtZQUNILElBQU0sQ0FBQyxHQUFzQixRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3pELENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztZQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU3QixJQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7WUFDYixDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDO1lBQy9CLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNWLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hDO0lBQ0wsQ0FBQztJQUtELCtCQUFPLEdBQVA7UUFDSSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQyxDQUFDO1NBQ3pFO2FBQU07WUFDSCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDcEI7SUFDTCxDQUFDO0lBYUQsc0NBQWMsR0FBZCxVQUFlLFFBQWdCLEVBQUUsT0FBYTtRQUE5QyxpQkEyQkM7UUExQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0dBQW9HLEdBQUcsS0FBSSxDQUFDLEtBQUssR0FBRywyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7YUFDbEw7aUJBQU07Z0JBQ0gsSUFBTSxNQUFJLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbEMsTUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVsQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtvQkFDN0IsS0FBa0IsVUFBb0IsRUFBcEIsS0FBQSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFwQixjQUFvQixFQUFwQixJQUFvQixFQUFFO3dCQUFuQyxJQUFNLEdBQUcsU0FBQTt3QkFDVixNQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUM1QztpQkFDSjtnQkFFRCxNQUFJLENBQUMsa0JBQWtCLEdBQUc7b0JBQ3RCLElBQUksTUFBSSxDQUFDLFVBQVUsS0FBSyxDQUFDLEVBQUU7d0JBQ3ZCLElBQUksTUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFOzRCQUUxQyxPQUFPLENBQUMsTUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO3lCQUM5Qjs2QkFBTTs0QkFDSCxNQUFNLENBQUMsTUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUN2QjtxQkFDSjtnQkFDTCxDQUFDLENBQUM7Z0JBQ0YsTUFBSSxDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFhRCw2Q0FBcUIsR0FBckIsVUFBc0IsUUFBZ0IsRUFBRSxPQUFhO1FBQXJELGlCQStCQztRQTlCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxLQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFFBQVEsRUFBRTtnQkFDNUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyR0FBMkcsR0FBRyxLQUFJLENBQUMsS0FBSyxHQUFHLDJDQUEyQyxDQUFDLENBQUMsQ0FBQzthQUN6TDtpQkFBTTtnQkFDSCxJQUFNLE1BQUksR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNsQyxNQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRWxDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO29CQUM3QixLQUFrQixVQUFvQixFQUFwQixLQUFBLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQXBCLGNBQW9CLEVBQXBCLElBQW9CLEVBQUU7d0JBQW5DLElBQU0sR0FBRyxTQUFBO3dCQUNWLE1BQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQzVDO2lCQUNKO2dCQUVELElBQU0sUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQztnQkFFdEQsTUFBSSxDQUFDLGtCQUFrQixHQUFHO29CQUN0QixJQUFJLE1BQUksQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFO3dCQUN2QixJQUFJLE1BQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTs0QkFFMUMsT0FBTyxDQUFDLE1BQUksQ0FBQyxZQUFZLENBQUMsQ0FBQzt5QkFDOUI7NkJBQU07NEJBQ0gsTUFBTSxDQUFDLE1BQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDdkI7cUJBQ0o7Z0JBQ0wsQ0FBQyxDQUFDO2dCQUVGLE1BQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDdkI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLTyxxQ0FBYSxHQUFyQjtRQUNJLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFL0UsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFFakIsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxRQUFRLENBQUM7SUFDN0MsQ0FBQztJQUVMLG9CQUFDO0FBQUQsQ0FsVkEsQUFrVkMsSUFBQTtBQWxWWSxzQ0FBYTs7Ozs7QUNsQjFCLGlEQUFnRDtBQUNoRCx5Q0FBd0M7QUFDeEMscUNBQW9DO0FBRXBDLG9HQUFtRztBQUluRyx5RUFBMkY7QUFDM0YsNkVBQTRFO0FBRTVFLDJGQUE2RjtBQUM3RixrRkFBb0Y7QUFFcEYsbURBQXNEO0FBQ3RELDZFQUFnRjtBQUNoRixtQ0FBc0M7QUFDdEMsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sS0FBSyxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsRUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsSSxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxRQUFRLENBQUMsRUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLElBQUksSUFBSSxpQkFBaUIsQ0FBQztBQUt0RyxJQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQVVsRDtJQXFERTtRQUFBLGlCQTRFQztRQXRIRCxlQUFVLEdBQWdCLEVBQUUsQ0FBQztRQVk3QixXQUFNLEdBQUcsRUFBRSxDQUFDO1FBSVosYUFBUSxHQUFHLEtBQUssQ0FBQztRQVlqQiwwQkFBcUIsR0FBa0MsRUFBRSxDQUFDO1FBSTFELHdCQUFtQixHQUFXLENBQUMsQ0FBQztRQVFoQyxPQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUdyQixJQUFJLENBQUMsY0FBYyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFFMUMsT0FBTyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRWpFLElBQUksUUFBUSxDQUFDLEVBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLFFBQVEsQ0FBQyxFQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUVsRSxNQUFPLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLEVBQUU7Z0JBQ2xELEtBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQUEsU0FBUztvQkFDL0IsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLHNCQUFzQixJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO3dCQUU5SSxJQUFJLFVBQVEsR0FBRyxDQUFDLENBQUM7d0JBRWpCLElBQU0sVUFBUSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQzt3QkFDeEQsSUFBTSxXQUFTLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDO3dCQUUxRCxJQUFNLHVCQUFxQixHQUFHOzRCQUM1QixPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07Z0NBQ2pDLElBQUksUUFBUSxDQUFDLFlBQVksQ0FBQyxFQUFFO29DQUUxQixPQUFPLENBQUM7d0NBQ04sUUFBUSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVTt3Q0FDbkUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVztxQ0FDdEUsQ0FBQyxDQUFDO2lDQUNKO3FDQUFNO29DQUlMLElBQU0sZUFBZSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7b0NBQzVGLElBQU0sUUFBUSxHQUFXLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO29DQUNuSixJQUFNLFNBQVMsR0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQ0FDdEosT0FBTyxDQUFDLEVBQUUsUUFBUSxVQUFBLEVBQUUsU0FBUyxXQUFBLEVBQUUsQ0FBQyxDQUFDO2lDQUNsQzs0QkFDSCxDQUFDLENBQUMsQ0FBQzt3QkFDTCxDQUFDLENBQUM7d0JBRUYsSUFBTSxtQkFBaUIsR0FBRyxXQUFXLENBQUM7NEJBQ3BDLHVCQUFxQixFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUEsYUFBYTtnQ0FDeEMsZ0NBQThCLENBQUMsVUFBUSxFQUFFLFdBQVMsRUFBRSxhQUFhLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQzs0QkFDdkcsQ0FBQyxDQUFDLENBQUM7d0JBQ0wsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUVQLElBQU0sZ0NBQThCLEdBQUcsVUFBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTOzRCQUM5RSxVQUFRLEVBQUUsQ0FBQzs0QkFDWCxJQUFJLFVBQVEsR0FBRyxFQUFFLEVBQUU7Z0NBQ2pCLFlBQVksQ0FBQyxtQkFBaUIsQ0FBQyxDQUFDOzZCQUNqQzs0QkFDRCxJQUFJLFFBQVEsS0FBSyxRQUFRLElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRTtnQ0FDcEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEdBQUc7b0NBQ2pDLEtBQUssRUFBRSxRQUFRLElBQUksQ0FBQztvQ0FDcEIsTUFBTSxFQUFFLFNBQVMsSUFBSSxDQUFDO2lDQUN2QixDQUFDO2dDQUNGLEtBQUksQ0FBQyxXQUFXLENBQ2QsdUJBQXVCLEVBQ3ZCO29DQUNFLFFBQVEsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVE7b0NBQ25DLFFBQVEsRUFBRSxpQkFBaUI7b0NBQzNCLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDO29DQUMxRCxNQUFNLEVBQUUsZUFBZTtpQ0FDeEIsRUFDRCxVQUFDLEtBQUssRUFBRSxRQUFRO29DQUNkLElBQUksS0FBSyxFQUFFO3dDQUNULE9BQU8sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxDQUFDLENBQUM7cUNBQ3JFO3lDQUFNO3dDQUNMLEtBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7d0NBQ2hPLFNBQVMsQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHVEQUEwQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO3FDQUMzTjtnQ0FDSCxDQUFDLENBQUMsQ0FBQztnQ0FDTCxZQUFZLENBQUMsbUJBQWlCLENBQUMsQ0FBQzs2QkFDakM7d0JBQ0gsQ0FBQyxDQUFDO3FCQUNIO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFNRCw4QkFBVyxHQUFYO1FBQ0UsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGlCQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUE0QkQsZ0NBQWEsR0FBYixVQUFjLGFBQW1DLEVBQUUsTUFBTyxFQUFFLE1BQU87UUFFakUsSUFBSSxVQUErQixDQUFDO1FBRXBDLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLE9BQU8sTUFBTSxLQUFLLFVBQVUsQ0FBQyxFQUFFO1lBSTlDLFVBQVUsR0FBeUIsTUFBTyxDQUFDO1lBRTNDLFVBQVUsR0FBRztnQkFDWCxXQUFXLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ2pHLFNBQVMsRUFBRSxDQUFDLE9BQU8sZ0JBQWdCLEtBQUssV0FBVyxJQUFJLFVBQVUsQ0FBQyxXQUFXLFlBQVksZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxVQUFVLENBQUMsU0FBUyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQzNNLFVBQVUsRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFVBQVUsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sVUFBVSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsaUNBQWUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsaUNBQWUsQ0FBQyxNQUFNO2dCQUNwTSxNQUFNLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxNQUFNLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQzdFLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsWUFBWSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsWUFBWSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUMvRixVQUFVLEVBQUUsQ0FBQyxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sVUFBVSxDQUFDLFVBQVUsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUM5TSxXQUFXLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ2pHLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTTthQUMxQixDQUFDO1NBQ0g7YUFBTTtZQUlMLFVBQVUsR0FBRztnQkFDWCxVQUFVLEVBQUUsaUNBQWUsQ0FBQyxNQUFNO2dCQUNsQyxNQUFNLEVBQUUsSUFBSTtnQkFDWixZQUFZLEVBQUUsSUFBSTtnQkFDbEIsWUFBWSxFQUFFLElBQUk7Z0JBQ2xCLFVBQVUsRUFBRSxTQUFTO2FBQ3RCLENBQUM7U0FDSDtRQUVELElBQU0sU0FBUyxHQUFjLElBQUkscUJBQVMsQ0FBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVFLElBQUksaUJBQXFELENBQUM7UUFDMUQsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxDQUFDLEVBQUU7WUFDOUMsaUJBQWlCLEdBQUcsTUFBTSxDQUFDO1NBQzVCO2FBQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO1lBQ25CLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztTQUM1QjtRQUVELFNBQVMsQ0FBQyxVQUFVLEVBQUU7YUFDbkIsSUFBSSxDQUFDO1lBQ0osSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7Z0JBQ25DLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQzlCO1lBQ0QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUMsS0FBSztZQUNiLElBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFO2dCQUNuQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMxQjtZQUNELFNBQVMsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFXRCxxQ0FBa0IsR0FBbEIsVUFBbUIsYUFBbUMsRUFBRSxVQUFnQztRQUF4RixpQkFtQkM7UUFsQkMsT0FBTyxJQUFJLE9BQU8sQ0FBWSxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRTVDLElBQUksU0FBb0IsQ0FBQztZQUV6QixJQUFNLFFBQVEsR0FBRyxVQUFDLEtBQVk7Z0JBQzVCLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtvQkFDWCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ2Y7cUJBQU07b0JBQ0wsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUNwQjtZQUNILENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRTtnQkFDaEIsU0FBUyxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQzthQUNyRTtpQkFBTTtnQkFDTCxTQUFTLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDekQ7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFPRCxvQ0FBaUIsR0FBakIsVUFBa0IsTUFBYztRQUM5QixPQUFPLElBQUksNkJBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBT0QsMENBQXVCLEdBQXZCO1FBQ0UsSUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUM5QixJQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsRUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNwQyxJQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztRQUdwRSxJQUFJLE1BQU0sS0FBSyxLQUFLLElBQUksQ0FBQyxPQUFPLEtBQUssUUFBUSxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3hILE9BQU8sQ0FBQyxDQUFDO1NBQ1Y7UUFJRCxJQUNFLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQztZQUN0QixDQUFDLE9BQU8sS0FBSyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxlQUFlLENBQUM7WUFDdkQsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssZ0JBQWdCLENBQUM7WUFDekQsQ0FBQyxPQUFPLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssY0FBYyxDQUFDO1lBQ3JELENBQUMsT0FBTyxLQUFLLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssVUFBVSxDQUFDLEVBQzNEO1lBQ0EsT0FBTyxDQUFDLENBQUM7U0FDVjthQUFNO1lBQ0wsT0FBTyxDQUFDLENBQUM7U0FDVjtJQUNILENBQUM7SUFPRCxpREFBOEIsR0FBOUI7UUFDRSxJQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQzlCLElBQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxFQUFJLENBQUMsTUFBTSxDQUFDO1FBR3BDLElBQUksTUFBTSxLQUFLLEtBQUssSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1lBQzVDLE9BQU8sQ0FBQyxDQUFDO1NBQ1Y7UUFFRCxJQUFJLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQyxFQUFFO1lBQzFHLE9BQU8sQ0FBQyxDQUFDO1NBQ1Y7YUFBTTtZQUNMLE9BQU8sQ0FBQyxDQUFDO1NBQ1Y7SUFDSCxDQUFDO0lBTUQsNkJBQVUsR0FBVjtRQUNFLE9BQU8sSUFBSSxPQUFPLENBQVcsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMzQyxTQUFTLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztnQkFDekQsSUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO2dCQUc3QixJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRTtvQkFDM0YsT0FBTyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFDLGFBQXVCO3dCQUN4RixJQUFJLGtCQUFrQixHQUFhLEVBQUUsQ0FBQzt3QkFDdEMsSUFBSSxZQUFZLEdBQWEsRUFBRSxDQUFDO3dCQUNoQyxJQUFJLFlBQVksR0FBYSxFQUFFLENBQUM7d0JBQ2hDLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsVUFBQyxNQUFjLElBQUssT0FBQSxNQUFNLENBQUMsSUFBSSxLQUFLLFlBQVksRUFBNUIsQ0FBNEIsQ0FBQyxDQUFDO3dCQUM1RixZQUFZLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFDLE1BQWMsSUFBSyxPQUFBLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUE1QixDQUE0QixDQUFDLENBQUM7d0JBQ3BGLFlBQVksR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQUMsTUFBYyxJQUFLLE9BQUEsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZLEVBQTVCLENBQTRCLENBQUMsQ0FBQzt3QkFDcEYsWUFBWSxDQUFDLE9BQU8sQ0FBQyxVQUFDLFVBQVUsRUFBRSxLQUFLOzRCQUNyQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRTtnQ0FDckIsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dDQUNmLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRTtvQ0FDZixLQUFLLEdBQUcsY0FBYyxDQUFDO2lDQUN4QjtxQ0FBTSxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7b0NBQ3RCLEtBQUssR0FBRyxhQUFhLENBQUM7aUNBQ3ZCO3FDQUFNO29DQUNMLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQztpQ0FDMUI7Z0NBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQztvQ0FDWCxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7b0NBQ3JCLFFBQVEsRUFBRSxVQUFVLENBQUMsUUFBUTtvQ0FDN0IsS0FBSyxFQUFFLEtBQUs7aUNBQ2IsQ0FBQyxDQUFDOzZCQUVKO2lDQUFNO2dDQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0NBQ1gsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO29DQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7b0NBQzdCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztpQ0FDeEIsQ0FBQyxDQUFDOzZCQUNKO3dCQUNILENBQUMsQ0FBQyxDQUFDO3dCQUNILFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBQyxVQUFVLEVBQUUsS0FBSzs0QkFDckMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUU7Z0NBQ3JCLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztnQ0FDZixRQUFRLEtBQUssRUFBRTtvQ0FDYixLQUFLLENBQUM7d0NBQ0osS0FBSyxHQUFHLFNBQVMsQ0FBQzt3Q0FDbEIsTUFBTTtvQ0FDUixLQUFLLENBQUM7d0NBQ0osSUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQXpCLENBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3Q0FDcEYsS0FBSyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUM7d0NBQ2xFLE1BQU07b0NBQ1IsS0FBSyxDQUFDO3dDQUNKLElBQU0sVUFBVSxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUF6QixDQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0NBQ2xGLElBQUksVUFBVSxFQUFFOzRDQUNkLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDO3lDQUMxQjs2Q0FBTTs0Q0FDTCxLQUFLLEdBQUcsa0JBQWtCLENBQUM7eUNBQzVCO3dDQUNELE1BQU07b0NBQ1IsS0FBSyxDQUFDO3dDQUNKLElBQU0sYUFBYSxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUE3QixDQUE2QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0NBQ3pGLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQzt3Q0FDekQsTUFBTTtvQ0FDUjt3Q0FDRSxLQUFLLEdBQUcsb0JBQW9CLENBQUM7d0NBQzdCLE1BQU07aUNBQ1Q7Z0NBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQztvQ0FDWCxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7b0NBQ3JCLFFBQVEsRUFBRSxVQUFVLENBQUMsUUFBUTtvQ0FDN0IsS0FBSyxFQUFFLEtBQUs7aUNBQ2IsQ0FBQyxDQUFDOzZCQUVKO2lDQUFNO2dDQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0NBQ1gsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO29DQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7b0NBQzdCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztpQ0FDeEIsQ0FBQyxDQUFDOzZCQUNKO3dCQUNILENBQUMsQ0FBQyxDQUFDO3dCQUNILE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkIsQ0FBQyxDQUFDLENBQUM7aUJBQ0o7cUJBQU07b0JBR0wsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFBLFVBQVU7d0JBQzVCLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUU7NEJBQ3hFLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0NBQ1gsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2dDQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7Z0NBQzdCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSzs2QkFDeEIsQ0FBQyxDQUFDO3lCQUNKO29CQUNILENBQUMsQ0FBQyxDQUFDO29CQUNILE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDbEI7WUFDSCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBQyxLQUFLO2dCQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzlDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQW1ERCwrQkFBWSxHQUFaLFVBQWEsT0FBNEI7UUFBekMsaUJBdUJDO1FBdEJDLE9BQU8sSUFBSSxPQUFPLENBQWMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUM5QyxLQUFJLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDO2lCQUNuQyxJQUFJLENBQUMsVUFBQSxXQUFXO2dCQUNmLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQztxQkFDN0MsSUFBSSxDQUFDLFVBQUEsV0FBVztvQkFDZixPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ3ZCLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLO29CQUNWLElBQUksU0FBNEIsQ0FBQztvQkFDakMsSUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN0QyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxLQUFLLFFBQVEsQ0FBQyxFQUFFO3dCQUN2QyxTQUFTLEdBQUcsaUNBQWlCLENBQUMsb0JBQW9CLENBQUM7cUJBQ3BEO3lCQUFNO3dCQUNMLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyxxQkFBcUIsQ0FBQztxQkFDckQ7b0JBQ0QsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDckQsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBb0I7Z0JBQzFCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQU9ELGlDQUFjLEdBQWQ7UUFDRSxPQUFPLENBQUMsR0FBRyxHQUFHLGNBQVEsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxLQUFLLEdBQUcsY0FBUSxDQUFDLENBQUM7UUFDMUIsT0FBTyxDQUFDLElBQUksR0FBRyxjQUFRLENBQUMsQ0FBQztRQUN6QixPQUFPLENBQUMsSUFBSSxHQUFHLGNBQVEsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFVRCwyQ0FBd0IsR0FBeEIsVUFBeUIsYUFBNEM7UUFDbkUsSUFBSSxDQUFDLHFCQUFxQixHQUFHLGFBQWEsQ0FBQztJQUM3QyxDQUFDO0lBUUQsMkNBQXdCLEdBQXhCLFVBQXlCLG1CQUF3QztRQUFqRSxpQkE4SkM7UUE3SkMsT0FBTyxJQUFJLE9BQU8sQ0FBeUIsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUN6RCxJQUFJLEtBQUssRUFBRSxLQUFLLENBQUM7WUFFakIsSUFBSSxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssSUFBSSxJQUFJLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUU7Z0JBQ3pGLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDZjtpQkFBTSxJQUFJLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUU7Z0JBQ3hELEtBQUssR0FBRyxJQUFJLENBQUM7YUFDZDtpQkFBTTtnQkFDTCxLQUFLLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDO2FBQ3pDO1lBRUQsSUFBSSxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssSUFBSSxJQUFJLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUU7Z0JBQ3pGLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDZjtpQkFBTTtnQkFDTCxLQUFLLEdBQUc7b0JBQ04sTUFBTSxFQUFFO3dCQUNOLEtBQUssRUFBRSxHQUFHO3FCQUNYO29CQUNELEtBQUssRUFBRTt3QkFDTCxLQUFLLEVBQUUsR0FBRztxQkFDWDtpQkFDRixDQUFDO2FBQ0g7WUFFRCxJQUFNLGdCQUFnQixHQUEyQjtnQkFDL0MsS0FBSyxPQUFBO2dCQUNMLEtBQUssT0FBQTthQUNOLENBQUM7WUFFRixJQUFJLE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxLQUFLLFFBQVEsRUFBRTtnQkFDOUMsZ0JBQWdCLENBQUMsS0FBSyxHQUFHLEVBQUUsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixDQUFDLEtBQUssRUFBRSxFQUFFLENBQUM7YUFDMUU7WUFFRCxJQUFJLGdCQUFnQixDQUFDLEtBQUssRUFBRTtnQkFFMUIsSUFBSSxDQUFDLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFO29CQUNwQyxJQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMvRSxJQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3hDLElBQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDeEMsZ0JBQWdCLENBQUMsS0FBYSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUNuRCxnQkFBZ0IsQ0FBQyxLQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7aUJBQ3ZEO2dCQUVELElBQUksQ0FBQyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRTtvQkFDbEMsZ0JBQWdCLENBQUMsS0FBYSxDQUFDLFNBQVMsR0FBRyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztpQkFDdEY7Z0JBRUQsSUFBSSxDQUFDLENBQUMsbUJBQW1CLENBQUMsV0FBVyxJQUFJLE9BQU8sbUJBQW1CLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtvQkFFNUYsSUFBSSxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssUUFBUTt3QkFDOUMsQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssUUFBUSxDQUFDO3dCQUMxRixDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRTt3QkFFekYsSUFBSSxDQUFDLEtBQUksQ0FBQyw4QkFBOEIsRUFBRSxFQUFFOzRCQUUxQyxJQUFNLEtBQUssR0FBRyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsNEJBQTRCLEVBQUUsNEZBQTRGLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUM5TCxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUNyQixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7eUJBRWY7NkJBQU07NEJBRUwsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRTtnQ0FFaEMsSUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDO2dDQUN6QixJQUFNLGlCQUFpQixHQUFXLG1CQUFtQixDQUFDLFdBQVcsQ0FBQztnQ0FDbEUsSUFBTSxnQkFBZ0IsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQ0FDL0YsZ0JBQWdCLENBQUMsT0FBTyxDQUFFLEdBQUc7b0NBQ2pDLFNBQVMsRUFBRTt3Q0FDVCxpQkFBaUIsRUFBRSxTQUFTO3dDQUM1QixtQkFBbUIsRUFBRSxnQkFBZ0I7cUNBQ3RDO2lDQUNGLENBQUM7Z0NBQ0YsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7NkJBRTNCO2lDQUFNO2dDQUVMLElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQywwQkFBMEIsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsRUFBRTtvQ0FJeEosYUFBYSxDQUFDLG9CQUFvQixDQUFDLFVBQUMsS0FBSyxFQUFFLGlCQUFpQjt3Q0FDMUQsSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLElBQUksaUJBQWlCLENBQUMsU0FBUyxDQUFDLGlCQUFpQixLQUFLLFFBQVEsRUFBRTs0Q0FDMUcsSUFBSSxLQUFLLEtBQUssbUJBQW1CLElBQUksS0FBSyxLQUFLLHVCQUF1QixFQUFFO2dEQUN0RSxJQUFNLE9BQUssR0FBRyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMscUJBQXFCLEVBQUUscURBQXFELENBQUMsQ0FBQztnREFDaEksT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFLLENBQUMsQ0FBQztnREFDckIsTUFBTSxDQUFDLE9BQUssQ0FBQyxDQUFDOzZDQUNmO2lEQUFNO2dEQUNMLElBQU0sV0FBVyxHQUFHLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQywwQkFBMkIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0RBQ3JHLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsVUFBQyxNQUFNO29EQUN6RCxJQUFJLE1BQU0sS0FBSyxvQkFBb0IsRUFBRTt3REFDbkMsSUFBTSxPQUFLLEdBQUcsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLHlCQUF5QixFQUFFLHNDQUFzQyxDQUFDLENBQUM7d0RBQ3JILE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBSyxDQUFDLENBQUM7d0RBQ3JCLE1BQU0sQ0FBQyxPQUFLLENBQUMsQ0FBQztxREFDZjtvREFDRCxJQUFJLE1BQU0sS0FBSyxlQUFlLEVBQUU7d0RBQzlCLElBQU0sT0FBSyxHQUFHLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyw4QkFBOEIsRUFBVyxLQUFJLENBQUMscUJBQXFCLENBQUMsMEJBQTJCLENBQUMsQ0FBQzt3REFDbkosT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFLLENBQUMsQ0FBQzt3REFDckIsTUFBTSxDQUFDLE9BQUssQ0FBQyxDQUFDO3FEQUNmO2dEQUNILENBQUMsQ0FBQyxDQUFDOzZDQUNKO3lDQUNGOzZDQUFNOzRDQUNMLGdCQUFnQixDQUFDLEtBQUssR0FBRyxpQkFBaUIsQ0FBQzs0Q0FDM0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7eUNBQzNCO29DQUNILENBQUMsQ0FBQyxDQUFDO2lDQUVKO3FDQUFNO29DQUVMLElBQUksU0FBUyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFO3dDQUU3QyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztxQ0FDM0I7eUNBQU07d0NBRUwsSUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO3dDQUU3RyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxpQkFBaUI7NENBQzlFLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtnREFDWCxJQUFJLEtBQUssS0FBSyxlQUFlLEVBQUU7b0RBQzdCLElBQU0sWUFBWSxHQUFHLENBQUMsQ0FBQyxLQUFJLENBQUMscUJBQXFCLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO3dEQUNwSSxtR0FBbUcsQ0FBQztvREFDdEcsSUFBTSxPQUFLLEdBQUcsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDhCQUE4QixFQUFFLFlBQVksQ0FBQyxDQUFDO29EQUNoRyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQUssQ0FBQyxDQUFDO29EQUNyQixNQUFNLENBQUMsT0FBSyxDQUFDLENBQUM7aURBQ2Y7cURBQU0sSUFBSSxLQUFLLEtBQUssb0JBQW9CLEVBQUU7b0RBQ3pDLElBQU0sT0FBSyxHQUFHLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyx5QkFBeUIsRUFBRSxzQ0FBc0MsQ0FBQyxDQUFDO29EQUNySCxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQUssQ0FBQyxDQUFDO29EQUNyQixNQUFNLENBQUMsT0FBSyxDQUFDLENBQUM7aURBQ2Y7cURBQU0sSUFBSSxLQUFLLEtBQUssbUJBQW1CLEVBQUU7b0RBQ3hDLElBQU0sT0FBSyxHQUFHLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxxQkFBcUIsRUFBRSxxREFBcUQsQ0FBQyxDQUFDO29EQUNoSSxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQUssQ0FBQyxDQUFDO29EQUNyQixNQUFNLENBQUMsT0FBSyxDQUFDLENBQUM7aURBQ2Y7NkNBQ0Y7aURBQU07Z0RBQ0wsZ0JBQWdCLENBQUMsS0FBSyxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQztnREFDakQsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7NkNBQzNCO3dDQUNILENBQUMsQ0FBQyxDQUFDO3FDQUNKO2lDQUNGO2dDQUVELG1CQUFtQixDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUM7NkJBRTVDO3lCQUNGO3FCQUNGO3lCQUFNO3dCQUVMLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQzt3QkFDaEYsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7cUJBQzNCO2lCQUNGO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2lCQUMzQjthQUNGO2lCQUFNO2dCQUNMLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2FBQzNCO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBS0QsMEJBQU8sR0FBUCxVQUFRLGVBQXVDO1FBQzdDLElBQU0sTUFBTSxHQUFHO1lBQ2IsU0FBUyxFQUFFLElBQUk7WUFDZixnQkFBZ0IsRUFBRSxLQUFLO1lBQ3ZCLEVBQUUsRUFBRTtnQkFDRixHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUs7Z0JBQ2YsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLFdBQVcsRUFBRSxlQUFlO2dCQUM1QixZQUFZLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ2hELGNBQWMsRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDcEQsYUFBYSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ25EO1lBQ0QsR0FBRyxFQUFFO2dCQUNILGNBQWMsRUFBRSxLQUFLO2dCQUNyQixpQkFBaUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUN0RSxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUM1RSxzQkFBc0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNoRixlQUFlLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDbEUsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDeEUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDcEUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDcEUsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUN6RCxxQkFBcUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUM5RSxxQkFBcUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUM5RSxZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDOUQsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQ3pEO1NBQ0YsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBS0QsMEJBQU8sR0FBUDtRQUNFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFLRCw4QkFBVyxHQUFYLFVBQVksTUFBYyxFQUFFLE1BQVcsRUFBRSxRQUFTO1FBQ2hELElBQUksTUFBTSxJQUFJLE1BQU0sWUFBWSxRQUFRLEVBQUU7WUFDeEMsUUFBUSxHQUFHLE1BQU0sQ0FBQztZQUNsQixNQUFNLEdBQUcsRUFBRSxDQUFDO1NBQ2I7UUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLDRCQUE0QixHQUFHLE1BQU0sR0FBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNwRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFLRCwyQkFBUSxHQUFSO1FBQ0UsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFLRCw0QkFBUyxHQUFUO1FBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFLRCw4QkFBVyxHQUFYO1FBQ0UsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFLTyxxQ0FBa0IsR0FBMUI7UUFDRSxPQUFPLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDMUMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ3BEO2FBQU07WUFDTCxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFTyx1Q0FBb0IsR0FBNUI7UUFDRSxPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRTtZQUMzQixLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFTyxzQ0FBbUIsR0FBM0I7UUFBQSxpQkFnQkM7UUFmQyxPQUFPLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDdEMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDL0YsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFO29CQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3JCLEtBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztvQkFDbkQsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUM7aUJBQ3REO3FCQUFNO29CQUNMLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQy9CLEtBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztpQkFDdEM7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNKO2FBQU07WUFDTCxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFTyxrQ0FBZSxHQUF2QjtRQUNFLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sWUFBWSxpQkFBTyxFQUFFO1lBQ2pFLE9BQU8sSUFBSSxDQUFDO1NBQ2I7YUFBTTtZQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztZQUMzQyxPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQztJQUVILGVBQUM7QUFBRCxDQXR5QkEsQUFzeUJDLElBQUE7QUF0eUJZLDRCQUFROzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoQ3JCLHFDQUFvQztBQUNwQyxtQ0FBa0M7QUFDbEMsaURBQWdEO0FBSWhELHNFQUFxRTtBQUNyRSxvR0FBbUc7QUFDbkcsa0ZBQWlGO0FBQ2pGLHlFQUEyRjtBQUczRixtQ0FBc0M7QUFLdEM7SUFBK0IsNkJBQWE7SUF5Q3hDLG1CQUFZLE1BQTRCLEVBQUUsVUFBK0IsRUFBRSxRQUFrQjtRQUE3RixZQUNJLGtCQUFNLElBQUksZUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxpQkFBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLFNBVXhKO1FBL0NELG1CQUFhLEdBQUcsS0FBSyxDQUFDO1FBS3RCLDBCQUFvQixHQUFHLEtBQUssQ0FBQztRQU9yQixrQkFBWSxHQUFHLEtBQUssQ0FBQztRQTBCekIsS0FBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFekIsS0FBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLHdCQUF3QixFQUFFLFVBQUMsTUFBYztZQUN2RCxLQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixHQUFHLEtBQUssQ0FBQztZQUMzQyxJQUFNLFdBQVcsR0FBRyxJQUFJLHlCQUFXLENBQUMsSUFBSSxFQUFFLEtBQUksRUFBRSxpQkFBaUIsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3hGLEtBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDOztJQUNQLENBQUM7SUFvQkQsZ0NBQVksR0FBWixVQUFhLEtBQWM7UUFBM0IsaUJBMEJDO1FBekJHLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEtBQUssS0FBSyxFQUFFO1lBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQkFDeEQsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtnQkFDMUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUM3Qix1QkFBdUIsRUFDdkI7b0JBQ0ksUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUTtvQkFDOUIsUUFBUSxFQUFFLGFBQWE7b0JBQ3ZCLFFBQVEsRUFBRSxLQUFLO29CQUNmLE1BQU0sRUFBRSxjQUFjO2lCQUN6QixFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQ1osSUFBSSxLQUFLLEVBQUU7d0JBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsRUFBRSxLQUFLLENBQUMsQ0FBQztxQkFDdkU7eUJBQU07d0JBQ0gsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDM0osS0FBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxFQUFFLEtBQUksQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQzlJO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2FBQ1Y7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDaEMsT0FBTyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ2xHO0lBQ0wsQ0FBQztJQW9CRCxnQ0FBWSxHQUFaLFVBQWEsS0FBYztRQUEzQixpQkEwQkM7UUF6QkcsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUU7WUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLO2dCQUN4RCxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUMxQixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2dCQUMxQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQzdCLHVCQUF1QixFQUN2QjtvQkFDSSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO29CQUM5QixRQUFRLEVBQUUsYUFBYTtvQkFDdkIsUUFBUSxFQUFFLEtBQUs7b0JBQ2YsTUFBTSxFQUFFLGNBQWM7aUJBQ3pCLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQkFDWixJQUFJLEtBQUssRUFBRTt3QkFDUCxPQUFPLENBQUMsS0FBSyxDQUFDLDZDQUE2QyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FCQUN2RTt5QkFBTTt3QkFDSCxLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUMzSixLQUFJLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztxQkFDOUk7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7YUFDVjtZQUNELElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUNoQyxPQUFPLENBQUMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLENBQUM7U0FDbEc7SUFDTCxDQUFDO0lBTUQscUNBQWlCLEdBQWpCLFVBQWtCLEtBQWU7UUFDN0IsS0FBSyxHQUFHLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM3QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQU1ELHNCQUFFLEdBQUYsVUFBRyxJQUFZLEVBQUUsT0FBK0I7UUFBaEQsaUJBK0JDO1FBOUJHLGlCQUFNLEVBQUUsWUFBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEIsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRTtnQkFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckc7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLDZCQUE2QixFQUFFO29CQUM3QyxLQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUkseUJBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLGVBQWUsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEcsQ0FBQyxDQUFDLENBQUM7YUFDTjtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssb0JBQW9CLEVBQUU7WUFDL0IsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUN2RSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUs7Z0JBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFO2dCQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbkg7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLGVBQWUsRUFBRTtZQUMxQixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ3BCLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZDO1NBQ0o7UUFDRCxJQUFJLElBQUksS0FBSyxjQUFjLEVBQUU7WUFDekIsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUN0QztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQU1ELHdCQUFJLEdBQUosVUFBSyxJQUFZLEVBQUUsT0FBK0I7UUFBbEQsaUJBK0JDO1FBOUJHLGlCQUFNLElBQUksWUFBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUIsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRTtnQkFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckc7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFO29CQUMvQyxLQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUkseUJBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLGVBQWUsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEcsQ0FBQyxDQUFDLENBQUM7YUFDTjtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssb0JBQW9CLEVBQUU7WUFDL0IsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUN2RSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUs7Z0JBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFO2dCQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbkg7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLGVBQWUsRUFBRTtZQUMxQixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ3BCLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZDO1NBQ0o7UUFDRCxJQUFJLElBQUksS0FBSyxjQUFjLEVBQUU7WUFDekIsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUN0QztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQVFELDhCQUFVLEdBQVY7UUFBQSxpQkFrV0M7UUFqV0csT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRS9CLElBQUksV0FBVyxHQUEyQixFQUFFLENBQUM7WUFDN0MsSUFBSSxjQUFjLEdBQTJCLEVBQUUsQ0FBQztZQUNoRCxJQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQztZQUNoQyxJQUFJLFNBQVMsQ0FBQztZQUVkLElBQU0sYUFBYSxHQUFHLFVBQUMsYUFBNEI7Z0JBQy9DLEtBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2dCQUN6QixLQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztnQkFDM0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzFCLENBQUMsQ0FBQztZQUVGLElBQU0sZUFBZSxHQUFHLFVBQUMsV0FBd0I7Z0JBQzdDLEtBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO2dCQUMxQixLQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFFMUIsSUFBSSxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsRUFBRTtvQkFDcEcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDekQsV0FBVyxDQUFDLFFBQVEsQ0FBb0IsS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFZLENBQUMsQ0FBQztpQkFDekU7Z0JBRUQsSUFBSSxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsRUFBRTtvQkFDcEcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDekQsV0FBVyxDQUFDLFFBQVEsQ0FBb0IsS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFZLENBQUMsQ0FBQztpQkFDekU7Z0JBR0QsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNuQyxJQUFNLE9BQU8sR0FBRyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxLQUFLLFNBQVMsSUFBSSxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQztvQkFDMUwsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7aUJBQ3JEO2dCQUNELElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDbkMsSUFBTSxPQUFPLEdBQUcsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxTQUFTLElBQUksS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUM7b0JBQzFMLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO2lCQUNyRDtnQkFFRCxLQUFJLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRXRELElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7b0JBQzVCLEtBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztpQkFDM0Q7Z0JBRUQsS0FBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBRXhDLElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxpQkFBaUIsRUFBRTtvQkFDMUIsS0FBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQW1CLEtBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7aUJBQzlHO2dCQUVELEtBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQztnQkFFNUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUU7b0JBR2hDLEtBQUksQ0FBQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsQ0FBQztpQkFDM0M7Z0JBQ0QsT0FBTyxLQUFJLENBQUMsaUJBQWlCLENBQUM7Z0JBRTlCLElBQUksS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsRUFBRTtvQkFDM0IsSUFBSSxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBRTdCLElBQUksUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFOzRCQUl0RCxLQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDOzRCQUMzQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7NEJBRS9DLElBQU0sb0JBQWtCLEdBQUc7Z0NBQ3ZCLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxHQUFHO29DQUMxQixLQUFLLEVBQUUsS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVO29DQUNyQyxNQUFNLEVBQUUsS0FBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXO2lDQUMxQyxDQUFDO2dDQUNGLEtBQUksQ0FBQyxNQUFNLENBQUMsMkJBQTJCLEdBQUcsSUFBSSxDQUFDO2dDQUMvQyxLQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMseUJBQXlCLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0NBQ3hELFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQzs0QkFDbkQsQ0FBQyxDQUFDOzRCQUVGLElBQUksVUFBUSxDQUFDOzRCQUNiLEtBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUU7Z0NBQ25ELElBQUksS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFO29DQUN0QyxVQUFRLEdBQUcsV0FBVyxDQUFDO3dDQUNuQixJQUFJLEtBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRTs0Q0FDdEMsYUFBYSxDQUFDLFVBQVEsQ0FBQyxDQUFDOzRDQUN4QixvQkFBa0IsRUFBRSxDQUFDO3lDQUN4QjtvQ0FDTCxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7aUNBQ1Y7cUNBQU07b0NBQ0gsb0JBQWtCLEVBQUUsQ0FBQztpQ0FDeEI7NEJBQ0wsQ0FBQyxDQUFDLENBQUM7eUJBQ047NkJBQU07NEJBSUcsSUFBQSxrREFBaUUsRUFBL0QsZ0JBQUssRUFBRSxrQkFBd0QsQ0FBQzs0QkFFeEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxRQUFRLENBQUMsRUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dDQUVwSCxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsR0FBRztvQ0FDMUIsS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO29DQUNsQixNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUM7aUNBQ3JCLENBQUM7NkJBQ0w7aUNBQU07Z0NBQ0gsS0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEdBQUc7b0NBQzFCLEtBQUssRUFBRSxLQUFLLElBQUksQ0FBQztvQ0FDakIsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDO2lDQUN0QixDQUFDOzZCQUNMOzRCQUNELEtBQUksQ0FBQyxNQUFNLENBQUMsMkJBQTJCLEdBQUcsSUFBSSxDQUFDOzRCQUMvQyxLQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMseUJBQXlCLEVBQUUsRUFBRSxDQUFDLENBQUM7eUJBQzNEO3FCQUNKO3lCQUFNO3dCQUVILEtBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUU7NEJBQ25ELEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxHQUFHO2dDQUMxQixLQUFLLEVBQUUsS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVO2dDQUNyQyxNQUFNLEVBQUUsS0FBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXOzZCQUMxQyxDQUFDOzRCQUNGLEtBQUksQ0FBQyx5QkFBeUIsR0FBRyxXQUFXLENBQUM7Z0NBQ3pDLElBQU0sZUFBZSxHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQ0FDdEUsSUFBTSxRQUFRLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQztnQ0FDcEksSUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQztnQ0FDdkksSUFBSSxLQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQjtvQ0FDbEMsQ0FBQyxRQUFRLEtBQUssS0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsS0FBSzt3Q0FDM0MsU0FBUyxLQUFLLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFO29DQUN2RCxJQUFNLFVBQVEsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDO29DQUMxRyxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsR0FBRzt3Q0FDMUIsS0FBSyxFQUFFLFFBQVEsSUFBSSxDQUFDO3dDQUNwQixNQUFNLEVBQUUsU0FBUyxJQUFJLENBQUM7cUNBQ3pCLENBQUM7b0NBQ0YsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUM3Qix1QkFBdUIsRUFDdkI7d0NBQ0ksUUFBUSxFQUFFLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUTt3Q0FDOUIsUUFBUSxFQUFFLGlCQUFpQjt3Q0FDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUM7d0NBQ3JELE1BQU0sRUFBRSxlQUFlO3FDQUMxQixFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7d0NBQ1osSUFBSSxLQUFLLEVBQUU7NENBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsRUFBRSxLQUFLLENBQUMsQ0FBQzt5Q0FDdkU7NkNBQU07NENBQ0gsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxVQUFRLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDOzRDQUN4TCxLQUFJLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxVQUFRLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO3lDQUMzSztvQ0FDTCxDQUFDLENBQUMsQ0FBQztpQ0FDVjs0QkFDTCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7NEJBQ1IsS0FBSSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUM7NEJBQy9DLEtBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDNUQsQ0FBQyxDQUFDLENBQUM7cUJBQ047aUJBQ0o7cUJBQU07b0JBQ0gsS0FBSSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUM7b0JBQy9DLEtBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQztpQkFDM0Q7Z0JBQ0QsT0FBTyxFQUFFLENBQUM7WUFDZCxDQUFDLENBQUM7WUFFRixJQUFNLGVBQWUsR0FBRyxVQUFDLFdBQXdCLEVBQUUsc0JBQXNCO2dCQUNyRSxLQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxFQUFFLGtCQUFrQixDQUFDLENBQUM7Z0JBQy9ELElBQUksS0FBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsSUFBSSxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFO29CQUV6RCxjQUFjLENBQUMsS0FBSyxHQUFHLHNCQUFzQixDQUFDO29CQUM5QyxjQUFjLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDN0IsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDdkIsS0FBSSxDQUFDLHdCQUF3QixDQUFDLGtCQUFrQixDQUFDLENBQUM7b0JBRWxELFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQzt5QkFDOUMsSUFBSSxDQUFDLFVBQUEsZUFBZTt3QkFDakIsS0FBSSxDQUFDLDBCQUEwQixDQUFDLFNBQVMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO3dCQUMvRCxXQUFXLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUMxRCxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBQ2pDLENBQUMsQ0FBQzt5QkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLO3dCQUNSLEtBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLEVBQUUsa0JBQWtCLENBQUMsQ0FBQzt3QkFDL0QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTs0QkFFeEIsS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQzt5QkFDdkM7d0JBQ0QsSUFBSSxTQUFTLEVBQUUsWUFBWSxDQUFDO3dCQUM1QixRQUFRLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7NEJBQzlCLEtBQUssZUFBZTtnQ0FDaEIsU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDO2dDQUMzRCxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dDQUNoQyxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO2dDQUMxRCxNQUFNOzRCQUNWLEtBQUssaUJBQWlCO2dDQUNsQixTQUFTLEdBQUcsaUNBQWlCLENBQUMsb0JBQW9CLENBQUM7Z0NBQ25ELFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0NBQ2hDLGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0NBQzFELE1BQU07NEJBQ1YsS0FBSyxzQkFBc0I7Z0NBQ3ZCLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxVQUFVLEVBQUU7b0NBQy9DLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyw0QkFBNEIsQ0FBQztvQ0FDM0QsWUFBWSxHQUFHLG9DQUFvQyxHQUEwRCxXQUFXLENBQUMsS0FBTSxDQUFDLFFBQVcsQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDO2lDQUNySztxQ0FBTTtvQ0FDSCxTQUFTLEdBQUcsaUNBQWlCLENBQUMsMEJBQTBCLENBQUM7b0NBQ3pELFlBQVksR0FBRyxzRUFBc0UsR0FBRyxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztpQ0FDbEg7Z0NBQ0QsYUFBYSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztnQ0FDMUQsTUFBTTt5QkFDYjtvQkFDTCxDQUFDLENBQUMsQ0FBQztpQkFDVjtxQkFBTTtvQkFDSCxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7aUJBQ2hDO1lBQ0wsQ0FBQyxDQUFDO1lBRUYsSUFBTSxhQUFhLEdBQUcsVUFBQSxLQUFLO2dCQUN2QixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQixLQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxFQUFFLGtCQUFrQixDQUFDLENBQUM7Z0JBQy9ELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7b0JBRXhCLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7aUJBQ3ZDO2dCQUNELElBQUksU0FBUyxFQUFFLFlBQVksQ0FBQztnQkFDNUIsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFO29CQUM5QixLQUFLLGVBQWU7d0JBQ2hCLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDOzRCQUNoQyxLQUFLLEVBQUUsS0FBSzs0QkFDWixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7eUJBQzNCLENBQUM7NkJBQ0csSUFBSSxDQUFDLFVBQUEsV0FBVzs0QkFDYixXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQ0FDdkMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOzRCQUNqQixDQUFDLENBQUMsQ0FBQzs0QkFDSCxTQUFTLEdBQUcsaUNBQWlCLENBQUMsNEJBQTRCLENBQUM7NEJBQzNELFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7NEJBQ2hDLGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7d0JBQzlELENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFBLENBQUM7NEJBQ04sU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDOzRCQUMzRCxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDOzRCQUNoQyxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO3dCQUM5RCxDQUFDLENBQUMsQ0FBQzt3QkFDUCxNQUFNO29CQUNWLEtBQUssaUJBQWlCO3dCQUNsQixTQUFTLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsaUNBQWlCLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLGlDQUFpQixDQUFDLG9CQUFvQixDQUFDO3dCQUMxSCxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUNoQyxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO3dCQUMxRCxNQUFNO29CQUNWLEtBQUssc0JBQXNCO3dCQUN2QixTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQzs0QkFDaEMsS0FBSyxFQUFFLEtBQUs7NEJBQ1osS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLO3lCQUMzQixDQUFDOzZCQUNHLElBQUksQ0FBQyxVQUFBLFdBQVc7NEJBQ2IsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7Z0NBQ3ZDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzs0QkFDakIsQ0FBQyxDQUFDLENBQUM7NEJBQ0gsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxLQUFLLFVBQVUsRUFBRTtnQ0FDL0MsU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDO2dDQUMzRCxZQUFZLEdBQUcsb0NBQW9DLEdBQTBELFdBQVcsQ0FBQyxLQUFNLENBQUMsUUFBVyxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUM7NkJBQ3JLO2lDQUFNO2dDQUNILFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQywwQkFBMEIsQ0FBQztnQ0FDekQsWUFBWSxHQUFHLHNFQUFzRSxHQUFHLEtBQUssQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDOzZCQUNsSDs0QkFDRCxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO3dCQUM5RCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBQSxDQUFDOzRCQUNOLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxVQUFVLEVBQUU7Z0NBQy9DLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyw0QkFBNEIsQ0FBQztnQ0FDM0QsWUFBWSxHQUFHLG9DQUFvQyxHQUEwRCxXQUFXLENBQUMsS0FBTSxDQUFDLFFBQVcsQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDOzZCQUNySztpQ0FBTTtnQ0FDSCxTQUFTLEdBQUcsaUNBQWlCLENBQUMsMEJBQTBCLENBQUM7Z0NBQ3pELFlBQVksR0FBRyxzRUFBc0UsR0FBRyxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQzs2QkFDbEg7NEJBQ0QsYUFBYSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQzt3QkFDOUQsQ0FBQyxDQUFDLENBQUM7d0JBQ1AsTUFBTTtvQkFDVixLQUFLLFlBQVksQ0FBQztvQkFDbEIsS0FBSyxrQkFBa0I7d0JBQ25CLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyxxQkFBcUIsQ0FBQzt3QkFDcEQsWUFBWSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQzt3QkFDaEMsYUFBYSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQzt3QkFDMUQsTUFBTTtvQkFDVjt3QkFDSSxTQUFTLEdBQUcsaUNBQWlCLENBQUMsYUFBYSxDQUFDO3dCQUM1QyxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUNoQyxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO3dCQUMxRCxNQUFNO2lCQUNiO1lBQ0wsQ0FBQyxDQUFBO1lBTUQsSUFBSSxDQUFDLE9BQU8sZ0JBQWdCLEtBQUssV0FBVyxJQUFJLEtBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQixJQUFJLENBQUMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUM7bUJBQ2pJLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLFlBQVksZ0JBQWdCLElBQUksQ0FBQyxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQzttQkFDcEksQ0FBQyxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxFQUFFO2dCQUNwSyxJQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLE9BQU8sZ0JBQWdCLEtBQUssV0FBVyxJQUFJLEtBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQixFQUFFO29CQUNwRyxXQUFXLENBQUMsUUFBUSxDQUFvQixLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVksQ0FBQyxDQUFDO2lCQUN6RTtnQkFDRCxJQUFJLE9BQU8sZ0JBQWdCLEtBQUssV0FBVyxJQUFJLEtBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQixFQUFFO29CQUNwRyxXQUFXLENBQUMsUUFBUSxDQUFvQixLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVksQ0FBQyxDQUFDO2lCQUN6RTtnQkFFRCxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBRTdCLE9BQU87YUFDVjtZQUVELEtBQUksQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsS0FBSSxDQUFDLFVBQVUsQ0FBQztpQkFDbEQsSUFBSSxDQUFDLFVBQUEsYUFBYTtnQkFFZixXQUFXLEdBQUcsYUFBYSxDQUFDO2dCQUU1QixJQUFNLHFCQUFxQixHQUFHO29CQUMxQixnQkFBZ0IsRUFBRSxXQUFXO29CQUM3QixtQkFBbUIsRUFBRSxLQUFJLENBQUMsVUFBVTtpQkFDdkMsQ0FBQztnQkFFRixLQUFJLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBRTVELElBQUksS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsSUFBSSxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFO29CQUN4RCxJQUFNLHdCQUFzQixHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDOUYsY0FBYyxDQUFDLEtBQUssR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHdCQUFzQixDQUFDO29CQUNuRixjQUFjLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7b0JBQ3pDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQ3ZCLEtBQUksQ0FBQyx3QkFBd0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO29CQUVsRCxJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLElBQUksU0FBUyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO3dCQUV6RyxTQUFTLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7NkJBQ3JELElBQUksQ0FBQyxVQUFBLFdBQVc7NEJBQ2IsZUFBZSxDQUFDLFdBQVcsRUFBRSx3QkFBc0IsQ0FBQyxDQUFDO3dCQUN6RCxDQUFDLENBQUM7NkJBQ0QsS0FBSyxDQUFDLFVBQUEsS0FBSzs0QkFDUixhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ3pCLENBQUMsQ0FBQyxDQUFDO3FCQUVWO3lCQUFNO3dCQUVILFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQzs2QkFDOUMsSUFBSSxDQUFDLFVBQUEsV0FBVzs0QkFDYixlQUFlLENBQUMsV0FBVyxFQUFFLHdCQUFzQixDQUFDLENBQUM7d0JBQ3pELENBQUMsQ0FBQzs2QkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLOzRCQUNSLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDekIsQ0FBQyxDQUFDLENBQUM7cUJBRVY7aUJBQ0o7cUJBQU07b0JBQ0gsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxtQkFBbUIsRUFDMUQsa0lBQWtJLENBQUMsQ0FBQyxDQUFDO2lCQUM1STtZQUNMLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsVUFBQyxLQUFvQjtnQkFDeEIsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QsaURBQTZCLEdBQTdCO1FBQ0ksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ2xELElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1NBQ25DO0lBQ0wsQ0FBQztJQUtPLDRDQUF3QixHQUFoQyxVQUFpQyxRQUFnQjtRQUFqRCxpQkFJQztRQUhHLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxVQUFVLENBQUM7WUFDdEMsS0FBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3QyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVPLDhDQUEwQixHQUFsQyxVQUFtQyxTQUFpQixFQUFFLFFBQWdCO1FBQ2xFLFlBQVksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FBQyxHQUFHLFFBQVEsRUFBRTtZQUVyQyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzVDO0lBQ0wsQ0FBQztJQUVMLGdCQUFDO0FBQUQsQ0ExbUJBLEFBMG1CQyxDQTFtQjhCLDZCQUFhLEdBMG1CM0M7QUExbUJZLDhCQUFTOzs7OztBQ2xCdEIsMkNBQTBDO0FBQzFDLG1DQUFrQztBQUtsQywyQ0FBMEM7QUFRMUMsOEVBQTZFO0FBQzdFLHNFQUFxRTtBQUVyRSw0RUFBMkU7QUFDM0UsZ0dBQStGO0FBQy9GLHNFQUFxRTtBQUNyRSxzRUFBcUU7QUFDckUsb0dBQW1HO0FBQ25HLHlFQUEyRjtBQUMzRiw2RUFBNEU7QUFFNUUsbURBQXNEO0FBQ3RELG1DQUFzQztBQU90QztJQTJESSxpQkFBWSxRQUFrQjtRQTVDOUIsbUJBQWMsR0FBb0IsRUFBRSxDQUFDO1FBWXJDLHlCQUFvQixHQUFvQixFQUFFLENBQUM7UUFLM0MsOEJBQXlCLEdBQUcsSUFBSSxDQUFDO1FBSWpDLDBDQUFxQyxHQUFHLElBQUksQ0FBQztRQUk3QyxzQkFBaUIsR0FBdUIsRUFBRSxDQUFDO1FBWTNDLDBCQUFxQixHQUFHLEtBQUssQ0FBQztRQUV0QixPQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQU01QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUM3QixDQUFDO0lBZ0NELHlCQUFPLEdBQVAsVUFBUSxLQUFhLEVBQUUsUUFBYztRQUFyQyxpQkFxQkM7UUFwQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRS9CLEtBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekIsSUFBSSxLQUFJLENBQUMsUUFBUSxDQUFDLHVCQUF1QixFQUFFLEVBQUU7Z0JBRXpDLEtBQUksQ0FBQyxPQUFPLEdBQUc7b0JBQ1gsU0FBUyxFQUFFLEtBQUksQ0FBQyxTQUFTO29CQUN6QixhQUFhLEVBQUUsS0FBSztvQkFDcEIsUUFBUSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtpQkFDbEUsQ0FBQztnQkFDRixLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDeEIsT0FBTyxFQUFFLENBQUM7Z0JBQ2QsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSztvQkFDVixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQyxDQUFDO2FBQ047aUJBQU07Z0JBQ0gsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxxQkFBcUIsRUFBRSxVQUFVLEdBQUcsUUFBUSxDQUFDLElBQUksR0FBRyxZQUFZLEdBQUcsUUFBUSxDQUFDLE9BQU8sR0FBRyxRQUFRLEdBQUcsUUFBUSxDQUFDLEVBQUksQ0FBQyxNQUFNLEdBQUcsK0JBQStCLENBQUMsQ0FBQyxDQUFDO2FBQ3hNO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBNkJELDRCQUFVLEdBQVY7UUFDSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBc0JELDJCQUFTLEdBQVQsVUFBVSxNQUFjLEVBQUUsYUFBbUMsRUFBRSxNQUFvRSxFQUFFLE1BQTZDO1FBQzlLLElBQUksVUFBVSxHQUF5QixFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsRUFBRTtZQUMxQyxVQUFVLEdBQUc7Z0JBQ1QsVUFBVSxFQUFFLENBQUMsT0FBTyxNQUFNLENBQUMsVUFBVSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxNQUFNLENBQUMsVUFBVSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQ0FBZSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQ0FBZSxDQUFDLE1BQU07Z0JBQ3hMLGdCQUFnQixFQUFFLENBQUMsT0FBTyxNQUFNLENBQUMsZ0JBQWdCLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDbkcsZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJO2FBQ3RHLENBQUM7U0FDTDthQUFNO1lBQ0gsVUFBVSxHQUFHO2dCQUNULFVBQVUsRUFBRSxpQ0FBZSxDQUFDLE1BQU07Z0JBQ2xDLGdCQUFnQixFQUFFLElBQUk7Z0JBQ3RCLGdCQUFnQixFQUFFLElBQUk7YUFDekIsQ0FBQztTQUNMO1FBRUQsSUFBSSxpQkFBcUQsQ0FBQztRQUMxRCxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLE1BQU0sS0FBSyxVQUFVLENBQUMsRUFBRTtZQUM1QyxpQkFBaUIsR0FBRyxNQUFNLENBQUM7U0FDOUI7YUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUU7WUFDakIsaUJBQWlCLEdBQUcsTUFBTSxDQUFDO1NBQzlCO1FBRUQsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWpFLE1BQU0sQ0FBQyxTQUFTLEVBQUU7YUFDYixJQUFJLENBQUM7WUFDRixPQUFPLENBQUMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDMUUsSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7Z0JBQ2pDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ2hDO1FBQ0wsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUEsS0FBSztZQUNSLElBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFO2dCQUNqQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QjtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ1AsSUFBTSxVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRTtZQUM1QixNQUFNLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQW1CLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUM3RztRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFTRCxnQ0FBYyxHQUFkLFVBQWUsTUFBYyxFQUFFLGFBQW1DLEVBQUUsVUFBaUM7UUFBckcsaUJBb0JDO1FBbkJHLE9BQU8sSUFBSSxPQUFPLENBQWEsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUUzQyxJQUFJLFVBQXNCLENBQUM7WUFFM0IsSUFBTSxRQUFRLEdBQUcsVUFBQyxLQUFZO2dCQUMxQixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7b0JBQ1QsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNqQjtxQkFBTTtvQkFDSCxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7aUJBQ3ZCO1lBQ0wsQ0FBQyxDQUFDO1lBRUYsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFO2dCQUNkLFVBQVUsR0FBRyxLQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQzVFO2lCQUFNO2dCQUNILFVBQVUsR0FBRyxLQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDaEU7UUFFTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFhRCw2QkFBVyxHQUFYLFVBQVksVUFBc0I7UUFDOUIsSUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDO1FBRS9ELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsWUFBWSxDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQ3JCLHNCQUFzQixFQUN0QixFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsRUFDckQsVUFBQyxLQUFLLEVBQUUsUUFBUTtZQUNaLElBQUksS0FBSyxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEdBQUcsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ3BFO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsOEJBQThCLEdBQUcsWUFBWSxDQUFDLENBQUM7YUFDL0Q7WUFDRCxVQUFVLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDdEMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNDLENBQUMsQ0FDSixDQUFDO1FBQ0YsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDdEQsQ0FBQztJQWdCRCx5QkFBTyxHQUFQLFVBQVEsU0FBb0I7UUFBNUIsaUJBaUNDO1FBaENHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixTQUFTLENBQUMsT0FBTyxHQUFHLEtBQUksQ0FBQztZQUN6QixTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRyxLQUFJLENBQUM7WUFFaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFO2dCQUVqQyxLQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzVDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO3FCQUNyQixJQUFJLENBQUM7b0JBQ0YsT0FBTyxFQUFFLENBQUM7Z0JBQ2QsQ0FBQyxDQUFDO3FCQUNELEtBQUssQ0FBQyxVQUFBLEtBQUs7b0JBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQzthQUNWO2lCQUFNO2dCQUVILFNBQVMsQ0FBQyxVQUFVLEVBQUU7cUJBQ2pCLElBQUksQ0FBQztvQkFDRixLQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQzVDLFNBQVMsQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO29CQUMxQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTt5QkFDckIsSUFBSSxDQUFDO3dCQUNGLE9BQU8sRUFBRSxDQUFDO29CQUNkLENBQUMsQ0FBQzt5QkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLO3dCQUNSLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbEIsQ0FBQyxDQUFDLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUMsS0FBSztvQkFDWCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQyxDQUFDO2FBQ1Y7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFzQkQsMkJBQVMsR0FBVCxVQUFVLFNBQW9CO1FBRTFCLElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFFaEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUU7WUFDcEIsT0FBTyxDQUFDLEtBQUssQ0FBQyw0REFBNEQsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNwRixPQUFPO1NBQ1Y7YUFBTSxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUM5QyxPQUFPLENBQUMsS0FBSyxDQUFDLGtGQUFrRjtnQkFDNUYsbUZBQW1GLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDakcsT0FBTztTQUNWO2FBQU07WUFFSCxPQUFPLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBRWxGLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ3hELElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQztpQkFDL0M7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFFaEMsSUFBTSxXQUFXLEdBQUcsSUFBSSx5QkFBVyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN2RyxTQUFTLENBQUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztTQUNyQztJQUNMLENBQUM7SUFvQkQsaUNBQWUsR0FBZixVQUFnQixVQUFzQjtRQUF0QyxpQkFxQkM7UUFwQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzdFLEtBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNyQixpQkFBaUIsRUFDakIsRUFBRSxZQUFZLEVBQUUsVUFBVSxDQUFDLFlBQVksRUFBRSxFQUN6QyxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsMENBQTBDLEdBQUcsVUFBVSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDM0YsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTt3QkFDcEIsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQywwQkFBMEIsRUFBRSxxREFBcUQsQ0FBQyxDQUFDLENBQUM7cUJBQ2xJO3lCQUFNO3dCQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDakI7aUJBQ0o7cUJBQU07b0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyw4Q0FBOEMsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3ZGLE9BQU8sRUFBRSxDQUFDO2lCQUNiO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFrQkQsZ0NBQWMsR0FBZCxVQUFlLE1BQWM7UUFBN0IsaUJBcUJDO1FBcEJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLCtCQUErQixHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoRSxLQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDckIsZ0JBQWdCLEVBQ2hCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFDN0IsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLEtBQUssRUFBRTtvQkFDUCxPQUFPLENBQUMsS0FBSyxDQUFDLHFDQUFxQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQzlFLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUscURBQXFELENBQUMsQ0FBQyxDQUFDO3FCQUNsSTt5QkFBTTt3QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMxRSxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBZUQsd0JBQU0sR0FBTixVQUFPLE1BQXFCO1FBQTVCLGlCQW9DQztRQW5DRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFFL0IsSUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO1lBRXpCLElBQUksTUFBTSxDQUFDLEVBQUUsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQ25DLElBQU0sZUFBYSxHQUFhLEVBQUUsQ0FBQztnQkFFbkMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQSxVQUFVO29CQUN4QixlQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDaEQsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLGVBQWEsQ0FBQzthQUN2QztpQkFBTTtnQkFDSCxhQUFhLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQzVCO1lBRUQsYUFBYSxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUV2RCxJQUFJLE9BQU8sR0FBVyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7WUFDM0QsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFO2dCQUNYLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssU0FBUyxFQUFFO29CQUN2QyxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQztpQkFDakM7YUFDSjtZQUNELGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUM7WUFFaEMsS0FBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFO2dCQUNyQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUM7YUFDekMsRUFBRSxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNmLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtvQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ2pCO3FCQUFNO29CQUNILE9BQU8sRUFBRSxDQUFDO2lCQUNiO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFPRCxvQkFBRSxHQUFGLFVBQUcsSUFBWSxFQUFFLE9BQTBJO1FBRXZKLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxVQUFBLEtBQUs7WUFDbEIsSUFBSSxLQUFLLEVBQUU7Z0JBQ1AsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLDBCQUEwQixFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ3RFO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksR0FBRywwQkFBMEIsQ0FBQyxDQUFDO2FBQy9EO1lBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLEtBQUssd0JBQXdCLElBQUksSUFBSSxLQUFLLHVCQUF1QixFQUFFO1lBQ3ZFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFFbEMsS0FBSyxJQUFNLFlBQVksSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQy9DLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQ3hELElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFO29CQUN2QixHQUFHLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztpQkFDOUI7YUFDSjtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQU1ELHNCQUFJLEdBQUosVUFBSyxJQUFZLEVBQUUsT0FBMEk7UUFFekosSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFVBQUEsS0FBSztZQUNwQixJQUFJLEtBQUssRUFBRTtnQkFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDdEU7aUJBQU07Z0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLDBCQUEwQixDQUFDLENBQUM7YUFDL0Q7WUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLElBQUksS0FBSyx3QkFBd0IsSUFBSSxJQUFJLEtBQUssdUJBQXVCLEVBQUU7WUFDdkUsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztZQUVsQyxLQUFLLElBQU0sWUFBWSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDL0MsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDeEQsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxRQUFRLEVBQUU7b0JBQ3ZCLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2lCQUNsQzthQUNKO1NBQ0o7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBTUQscUJBQUcsR0FBSCxVQUFJLElBQVksRUFBRSxPQUEySTtRQUV6SixJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNwQzthQUFNO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzlCO1FBRUQsSUFBSSxJQUFJLEtBQUssd0JBQXdCLElBQUksSUFBSSxLQUFLLHVCQUF1QixFQUFFO1lBQ3ZFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7WUFHbkMsS0FBSyxJQUFNLFlBQVksSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQy9DLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQ3hELElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRTtvQkFDUCxHQUFHLENBQUMscUJBQXFCLEVBQUUsQ0FBQztpQkFDL0I7YUFDSjtTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQVFELHFDQUFtQixHQUFuQixVQUFvQixRQUEyQjtRQUEvQyxpQkFZQztRQVZHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7YUFFOUIsSUFBSSxDQUFDLFVBQUEsVUFBVTtZQUNaLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEdBQUcscUNBQXFDLENBQUMsQ0FBQztRQUN0RixDQUFDLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQSxhQUFhO1lBQ2hCLElBQU0sVUFBVSxHQUFHLElBQUksdUJBQVUsQ0FBQyxLQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDbEQsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUM7WUFDakQsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLGlDQUFlLENBQUMsS0FBSyxFQUFFLEtBQUksRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUtELG1DQUFpQixHQUFqQixVQUFrQixHQUFHO1FBQXJCLGlCQXlCQztRQXhCRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxvQkFBb0IsR0FBRyxHQUFHLENBQUMsWUFBWSxHQUFHLHFDQUFxQztZQUN0SCwrQkFBK0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQzthQUVyRixJQUFJLENBQUMsVUFBQSxVQUFVO1lBQ1osSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtnQkFDckIsSUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztnQkFFakMsSUFBTSxXQUFXLEdBQUcsSUFBSSx5QkFBVyxDQUFDLElBQUksRUFBRSxLQUFJLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDdkYsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFFbEMsT0FBTyxLQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUVsRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDckQsS0FBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQztvQkFDdEMsS0FBSSxDQUFDLHFDQUFxQyxHQUFHLElBQUksQ0FBQztpQkFDckQ7YUFDSjtZQUNELE9BQU8sS0FBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2RCxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLElBQUksaUNBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLHFCQUFxQixFQUFFLFVBQVUsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hJLENBQUMsQ0FBQzthQUNELEtBQUssQ0FBQyxVQUFBLGFBQWE7WUFDaEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFLRCx3Q0FBc0IsR0FBdEIsVUFBdUIsUUFBMkI7UUFBbEQsaUJBbUNDO1FBakNHLElBQU0sb0JBQW9CLEdBQUcsVUFBQyxVQUFVO1lBQ3BDLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsVUFBVSxDQUFDO1lBRTdELElBQUksQ0FBQyxLQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFLeEQsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsZUFBZSxFQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzlHO1lBRUQsS0FBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2pFLENBQUMsQ0FBQztRQUlGLElBQUksVUFBc0IsQ0FBQztRQUMzQixJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxxQkFBcUIsR0FBRyxRQUFRLENBQUMsRUFBRSxHQUFHLDJDQUEyQztZQUNuSCwrQkFBK0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQzthQUVyRixJQUFJLENBQUMsVUFBQSxHQUFHO1lBRUwsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixRQUFRLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDN0IsVUFBVSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDOUIsVUFBVSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQSxhQUFhO1lBRWhCLFVBQVUsR0FBRyxJQUFJLHVCQUFVLENBQUMsS0FBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUtELDBDQUF3QixHQUF4QixVQUF5QixHQUFHO1FBQTVCLGlCQTZCQztRQTVCRyxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUU7WUFFbkQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN4QzthQUFNO1lBQ0gsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUscUJBQXFCLEdBQUcsR0FBRyxDQUFDLFlBQVksR0FBRyw2Q0FBNkM7Z0JBQy9ILCtCQUErQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO2lCQUVyRixJQUFJLENBQUMsVUFBQSxVQUFVO2dCQUVaLElBQU0sV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxJQUFJLEVBQUUsS0FBSSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRyxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2dCQUdsQyxJQUFNLFFBQVEsR0FBVyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQkFDcEQsT0FBTyxLQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRTNDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNyRCxLQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDO29CQUN0QyxLQUFJLENBQUMscUNBQXFDLEdBQUcsSUFBSSxDQUFDO2lCQUNyRDtnQkFFRCxVQUFVLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsVUFBQSxhQUFhO2dCQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxDQUFDO1NBQ1Y7SUFDTCxDQUFDO0lBS0Qsc0NBQW9CLEdBQXBCLFVBQXFCLEdBQUc7UUFDcEIsSUFBSSxHQUFHLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFO1lBRW5ELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRTtnQkFDL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ2hDO1NBQ0o7SUFDTCxDQUFDO0lBS0QsOEJBQVksR0FBWixVQUFhLEdBQUc7UUFBaEIsaUJBZ0JDO1FBZEcsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRW5ELElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyw2REFBNkQ7Y0FDaEgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsK0JBQStCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7YUFFdEgsSUFBSSxDQUFDLFVBQUEsVUFBVTtZQUNaLEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUkseUJBQVcsQ0FBQyxLQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyRixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUN2QixLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3hGO1FBQ0wsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUEsYUFBYTtZQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUtELHlDQUF1QixHQUF2QixVQUF3QixHQUFHO1FBQTNCLGlCQTJEQztRQXpERyxJQUFNLFFBQVEsR0FBRyxVQUFDLFVBQXNCO1lBQ3BDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssR0FBRyxDQUFDLFFBQVEsRUFBRTtnQkFDcEUsSUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztnQkFDakMsSUFBSSxRQUFRLFNBQUEsQ0FBQztnQkFDYixRQUFRLEdBQUcsQ0FBQyxRQUFRLEVBQUU7b0JBQ2xCLEtBQUssYUFBYTt3QkFDZCxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQzt3QkFDOUIsR0FBRyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQzt3QkFDdkMsTUFBTSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO3dCQUNsQyxNQUFNO29CQUNWLEtBQUssYUFBYTt3QkFDZCxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQzt3QkFDOUIsR0FBRyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQzt3QkFDdkMsTUFBTSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO3dCQUNsQyxNQUFNO29CQUNWLEtBQUssaUJBQWlCO3dCQUNsQixRQUFRLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQzt3QkFDbEMsR0FBRyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7d0JBQ3BELE1BQU0sQ0FBQyxlQUFlLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQzt3QkFDdEMsTUFBTTtvQkFDVixLQUFLLFFBQVE7d0JBQ1QsUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7d0JBQ3pCLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQzt3QkFDakYsSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRTs0QkFDNUIsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLGVBQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDOzRCQUNwRSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7NEJBQzlCLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUU7Z0NBQzdCLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDOzZCQUM5RDt5QkFDSjs2QkFBTTs0QkFDSCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7eUJBQ3hCO3dCQUNELEdBQUcsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzt3QkFDN0IsTUFBTTtpQkFDYjtnQkFDRCxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdJLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUU7b0JBQ3hCLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQzdLO2FBQ0o7aUJBQU07Z0JBQ0gsT0FBTyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxHQUFHLENBQUMsUUFBUSxHQUFHLDBCQUEwQixHQUFHLEdBQUcsQ0FBQyxZQUFZLEdBQUcsb0NBQW9DLENBQUMsQ0FBQzthQUNwSjtRQUNMLENBQUMsQ0FBQztRQUVGLElBQUksR0FBRyxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRTtZQUVuRCxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQzdCO2FBQU07WUFDSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxvQkFBb0IsR0FBRyxHQUFHLENBQUMsWUFBWSxHQUFHLDJDQUEyQztnQkFDNUgsK0JBQStCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7aUJBQ3JGLElBQUksQ0FBQyxVQUFBLFVBQVU7Z0JBQ1osUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pCLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsVUFBQSxhQUFhO2dCQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxDQUFDO1NBQ1Y7SUFDTCxDQUFDO0lBS0Qsa0NBQWdCLEdBQWhCLFVBQWlCLEdBQUc7UUFDaEIsSUFBTSxTQUFTLEdBQW9CO1lBQy9CLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBUztZQUN4QixTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVM7WUFDeEIsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVO1lBQzFCLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNWLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtZQUNkLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUTtZQUN0QixRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVE7WUFDdEIsY0FBYyxFQUFFLEdBQUcsQ0FBQyxjQUFjO1lBQ2xDLFdBQVcsRUFBRSxHQUFHLENBQUMsV0FBVztZQUM1QixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07WUFDbEIsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhO1lBQ2hDLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztZQUNwQixnQkFBZ0IsRUFBRSxHQUFHLENBQUMsZ0JBQWdCO1lBQ3RDLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtZQUNkLE1BQU0sRUFBRTtnQkFDSixPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN4QyxDQUFDO1NBQ0osQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLHdDQUF3QyxHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsR0FBRyxtQkFBbUIsR0FBRyxHQUFHLENBQUMsWUFBWSxHQUFHLG1DQUFtQyxHQUFHLFNBQVMsQ0FBQzthQUNuTSxJQUFJLENBQUMsVUFBQSxVQUFVO1lBQ1osSUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNqQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFBLEtBQUs7Z0JBQ3pELE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEdBQUcsTUFBTSxDQUFDLFFBQVE7c0JBQ3ZELHNCQUFzQixHQUFHLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3BFLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUEsYUFBYTtZQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUtELGlDQUFlLEdBQWYsVUFBZ0IsR0FBRztRQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELElBQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7UUFDeEIsSUFBSSxDQUFDLEtBQUssU0FBUyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLENBQUM7b0JBQ2pDLE9BQU8sRUFBRSxDQUFDO2lCQUNiLENBQUMsQ0FBQyxDQUFDO1NBQ1A7YUFBTTtZQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMscUNBQXFDLEVBQUUsR0FBRyxDQUFDLENBQUM7U0FDNUQ7SUFDTCxDQUFDO0lBS0Qsa0NBQWdCLEdBQWhCLFVBQWlCLE1BQWM7UUFDM0IsT0FBTyxDQUFDLElBQUksQ0FBQyw2QkFBNkIsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLHdCQUF3QixDQUFDLENBQUM7UUFDeEYsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFO1lBQy9DLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQzVCO0lBQ0wsQ0FBQztJQUtELHVDQUFxQixHQUFyQjtRQUNJLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRXRFLENBQUM7SUFLRCw4QkFBWSxHQUFaLFVBQWEsTUFBTTtRQUVmLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN4RCxJQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ3pCLElBQUksR0FBRyxFQUFFO1lBQ0wsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQzlCLEtBQUssRUFBRSxHQUFHO2lCQUNiLENBQUMsQ0FBQyxDQUFDO1NBQ1A7YUFBTTtZQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDbkU7SUFDTCxDQUFDO0lBS0Qsb0NBQWtCLEdBQWxCLFVBQW1CLFFBQVE7UUFDdkIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLCtCQUFjLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0SCxDQUFDO0lBS0Qsb0NBQWtCLEdBQWxCLFVBQW1CLFFBQVE7UUFDdkIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLCtCQUFjLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZJLENBQUM7SUFNRCx5Q0FBdUIsR0FBdkIsVUFBd0IsUUFBUTtRQUM1QixJQUFNLFlBQVksR0FBVyxRQUFRLENBQUMsWUFBWSxDQUFDO1FBQ25ELElBQU0sUUFBUSxHQUFXLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsdUNBQXVDLEdBQUcsWUFBWSxDQUFDO2FBQ25GLElBQUksQ0FBQyxVQUFBLFVBQVU7WUFDWixPQUFPLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDeEMsSUFBTSxNQUFNLEdBQVcsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUN6QyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSx5QkFBVyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNsSCxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFLRCwyQkFBUyxHQUFULFVBQVUsSUFBWSxFQUFFLFVBQWlCO1FBQ3JDLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBS0QsdUJBQUssR0FBTCxVQUFNLE1BQWUsRUFBRSxNQUFjO1FBQXJDLGlCQTRCQztRQTFCRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQztRQUV4RCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDdEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQ25ELElBQUksS0FBSyxFQUFFO3dCQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ3hCO29CQUNELEtBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVCLENBQUMsQ0FBQyxDQUFDO2FBQ047aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUMzQjtZQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVqQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7Z0JBRTNCLElBQU0sc0JBQXNCLEdBQUcsSUFBSSxtREFBd0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzFFLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO2dCQUNuRSxzQkFBc0IsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2FBQ2hEO1NBQ0o7YUFBTTtZQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQzNFO0lBQ0wsQ0FBQztJQUtPLDRCQUFVLEdBQWxCLFVBQW1CLEtBQWE7UUFBaEMsaUJBdUVDO1FBdEVHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7Z0JBQ3hCLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtvQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ2pCO3FCQUFNO29CQUVILElBQU0sVUFBVSxHQUFHO3dCQUNmLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO3dCQUM3QixPQUFPLEVBQUUsS0FBSSxDQUFDLFNBQVM7d0JBQ3ZCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUzt3QkFDbkUsUUFBUSxFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7d0JBQzlELE1BQU0sRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRTt3QkFDakMsUUFBUSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFO3FCQUN4QyxDQUFDO29CQUVGLEtBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTt3QkFDOUQsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFOzRCQUNULE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzt5QkFDakI7NkJBQU07NEJBR0gsS0FBSSxDQUFDLFlBQVksR0FBRztnQ0FDaEIsU0FBUyxFQUFFLElBQUk7Z0NBQ2YsT0FBTyxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFlBQVk7Z0NBQzVDLGNBQWMsRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxXQUFXO2dDQUNsRCxlQUFlLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssV0FBVzs2QkFDdEQsQ0FBQzs0QkFHRixLQUFJLENBQUMsVUFBVSxHQUFHLElBQUksdUJBQVUsQ0FBQyxLQUFJLENBQUMsQ0FBQzs0QkFDdkMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQzs0QkFDM0MsS0FBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQzs0QkFDbEQsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQzs0QkFDekMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQzs0QkFHbEQsSUFBTSxRQUFNLEdBQUc7Z0NBQ1gsV0FBVyxFQUFFLElBQUksS0FBSyxFQUFjO2dDQUNwQyxPQUFPLEVBQUUsSUFBSSxLQUFLLEVBQVU7NkJBQy9CLENBQUM7NEJBQ0YsSUFBTSxvQkFBb0IsR0FBd0IsUUFBUSxDQUFDLEtBQUssQ0FBQzs0QkFDakUsb0JBQW9CLENBQUMsT0FBTyxDQUFDLFVBQUEsV0FBVztnQ0FDcEMsSUFBTSxVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLEtBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztnQ0FDckQsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxVQUFVLENBQUM7Z0NBQzdELFFBQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dDQUNwQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFO29DQUNyQixLQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUM7b0NBQzdELFFBQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztpQ0FDMUM7NEJBQ0wsQ0FBQyxDQUFDLENBQUM7NEJBR0gsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLGlDQUFlLENBQUMsS0FBSyxFQUFFLEtBQUksRUFBRSxtQkFBbUIsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFHckgsUUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBQSxVQUFVO2dDQUNqQyxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLElBQUksaUNBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3BILENBQUMsQ0FBQyxDQUFDOzRCQUdILFFBQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTTtnQ0FDekIsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3BHLENBQUMsQ0FBQyxDQUFDOzRCQUVILE9BQU8sRUFBRSxDQUFDO3lCQUNiO29CQUNMLENBQUMsQ0FBQyxDQUFDO2lCQUNOO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxxQ0FBbUIsR0FBM0IsVUFBNEIsTUFBYztRQUN0QyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtZQUUxQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsc0JBQXNCLEVBQUU7Z0JBRS9DLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2FBQzNFO1NBQ0o7SUFDTCxDQUFDO0lBRU8sc0NBQW9CLEdBQTVCLFVBQTZCLFFBQWE7UUFDdEMsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUU7WUFDOUIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ25DO2FBQU07WUFDSCxPQUFPLFFBQVEsQ0FBQztTQUNuQjtJQUNMLENBQUM7SUFFTywrQkFBYSxHQUFyQixVQUFzQixZQUFvQixFQUFFLFlBQW9CO1FBQWhFLGlCQWdCQztRQWZHLE9BQU8sSUFBSSxPQUFPLENBQWEsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMzQyxJQUFNLFVBQVUsR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFO2dCQUVkLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN2QjtpQkFBTTtnQkFDSCxJQUFJLEtBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxLQUFLLFlBQVksRUFBRTtvQkFFL0MsT0FBTyxDQUFDLEtBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDNUI7cUJBQU07b0JBRUgsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztpQkFDNUU7YUFDSjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLHFDQUFtQixHQUEzQixVQUE0QixZQUFvQixFQUFFLFlBQW9CO1FBQXRFLGlCQVdDO1FBVkcsT0FBTyxJQUFJLE9BQU8sQ0FBYSxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQzNDLElBQU0sVUFBVSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUU7Z0JBRWQsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ3ZCO2lCQUFNO2dCQUVILE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7YUFDNUU7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyw4QkFBWSxHQUFwQixVQUFxQixLQUFhO1FBQzlCLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsNkVBQTZFLENBQUMsQ0FBQztRQUN6RyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7WUFDVCxJQUFNLEdBQUcsR0FBRztnQkFDUixRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2xCLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNkLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDakIsQ0FBQztZQUVGLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEMsSUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbkMsS0FBSyxDQUFDLEdBQUcsQ0FBQztpQkFDVixHQUFHLENBQUMsVUFBQSxLQUFLLElBQUksT0FBQSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFoQixDQUFnQixDQUFDO2lCQUM5QixNQUFNLENBQUMsVUFBQyxNQUFNLEVBQUUsRUFBWTtvQkFBWCxXQUFHLEVBQUUsYUFBSztnQkFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQTtnQkFDbkIsT0FBTyxNQUFNLENBQUE7WUFDakIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRVgsSUFBSSxDQUFDLFNBQVMsR0FBVyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEQsSUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JDLElBQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6QyxJQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDakQsSUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDckQsSUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pDLElBQU0sbUJBQW1CLEdBQUcsV0FBVyxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDL0QsSUFBTSxxQkFBcUIsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFckQsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUNWLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzthQUNqQztZQUNELElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRTtnQkFDWixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7YUFDakM7WUFDRCxJQUFJLENBQUMsQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRTtnQkFDcEMsSUFBTSxPQUFPLEdBQUcsT0FBTyxHQUFHLEdBQUcsQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO2dCQUNqRCxJQUFNLFFBQVEsR0FBRyxPQUFPLEdBQUcsR0FBRyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7Z0JBQ2xELElBQU0sUUFBUSxHQUFHLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQztnQkFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUc7b0JBQ3ZCLEVBQUUsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ25CLEVBQUUsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRTtpQkFDckYsQ0FBQztnQkFDRixPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixHQUFHLFlBQVksR0FBRyxHQUFHLEdBQUcsY0FBYyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2FBQ3RGO1lBQ0QsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO2dCQUNSLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQzthQUM3QjtZQUNELElBQUksQ0FBQyxDQUFDLG1CQUFtQixFQUFFO2dCQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixHQUFHLENBQUMsbUJBQW1CLENBQUM7YUFDNUQ7WUFDRCxJQUFJLENBQUMsQ0FBQyxxQkFBcUIsRUFBRTtnQkFDekIsT0FBTyxDQUFDLElBQUksQ0FBQywyQkFBMkIsR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUNsRSxJQUFJLHFCQUFxQixLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFO29CQUN4RCxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixHQUFHLHFCQUFxQjt3QkFDckQsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjO3dCQUN6RCx5REFBeUQsQ0FBQyxDQUFBO2lCQUNqRTthQUNKO1lBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsUUFBUSxHQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO1lBQ3hELElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLFVBQVUsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1NBRWpEO2FBQU07WUFDSCxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQTtTQUN0RDtJQUNMLENBQUM7SUFFTCxjQUFDO0FBQUQsQ0F4b0NBLEFBd29DQyxJQUFBO0FBeG9DWSwwQkFBTzs7Ozs7QUMvQnBCLG1DQUFrQztBQUdsQywyQ0FBMEM7QUFJMUMsd0VBQW1JO0FBQ25JLDJFQUEwRTtBQUMxRSw0RkFBMkY7QUFDM0Ysb0ZBQW1GO0FBQ25GLG9HQUFtRztBQUNuRyx5RUFBMkY7QUFFM0YsbURBQXNEO0FBQ3RELDJCQUE4QjtBQUM5QixtQ0FBc0M7QUFRdEM7SUE0SUksZ0JBQVksT0FBZ0IsRUFBRSxPQUEwRDtRQUF4RixpQkFzREM7UUEzR0QsT0FBRSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFNaEIsd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBS3BDLGdDQUEyQixHQUFHLEtBQUssQ0FBQztRQUlwQywyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFJL0Isa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFvQnRCLHVDQUFrQyxHQUFHLEtBQUssQ0FBQztRQUkzQyxzQ0FBaUMsR0FBRyxLQUFLLENBQUM7UUFJMUMsNkJBQXdCLEdBQUcsS0FBSyxDQUFDO1FBUTdCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBRXZCLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUU5QixJQUFJLENBQUMsaUJBQWlCLEdBQXlCLE9BQU8sQ0FBQztZQUN2RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO1lBQ3JELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQztZQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUM7WUFDaEQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQzthQUN6RDtZQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDZixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDO2dCQUMxRyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7Z0JBQzFHLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQzthQUNqRTtZQUNELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQzVGLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsY0FBYyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUMxSCxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO2lCQUN2RDtnQkFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUM7YUFDL0M7U0FDSjthQUFNO1lBRUgsSUFBSSxDQUFDLGtCQUFrQixHQUEwQixPQUFPLENBQUM7WUFFekQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFFbkMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUM7YUFDakY7WUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQztnQkFDOUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDO2dCQUN2RSxJQUFJLE9BQU8sZ0JBQWdCLEtBQUssV0FBVyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLFlBQVksZ0JBQWdCLEVBQUU7b0JBQ2hJLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDO2lCQUMvQjtxQkFBTTtvQkFDSCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7aUJBQ2hFO2FBQ0o7WUFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFO2dCQUN0RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUM7YUFDcEU7U0FDSjtRQUVELElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLHFCQUFxQixFQUFFO1lBQzlCLEtBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsS0FBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEdBQUcsS0FBSSxDQUFDLFdBQVcsR0FBRyx1QkFBdUIsR0FBRyxLQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQzFHLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU1ELG1CQUFFLEdBQUYsVUFBRyxJQUFZLEVBQUUsT0FBK0I7UUFBaEQsaUJBVUM7UUFURyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBQSxLQUFLO1lBQ2xCLElBQUksS0FBSyxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksR0FBRyx5QkFBeUIsR0FBRyxLQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUMzRjtpQkFBTTtnQkFDSCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcseUJBQXlCLEdBQUcsS0FBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsQ0FBQzthQUNwRjtZQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFNRCxxQkFBSSxHQUFKLFVBQUssSUFBWSxFQUFFLE9BQStCO1FBQWxELGlCQVVDO1FBVEcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFVBQUEsS0FBSztZQUNwQixJQUFJLEtBQUssRUFBRTtnQkFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsOEJBQThCLEdBQUcsS0FBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDaEc7aUJBQU07Z0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLDhCQUE4QixHQUFHLEtBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLENBQUM7YUFDekY7WUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBTUQsb0JBQUcsR0FBSCxVQUFJLElBQVksRUFBRSxPQUFnQztRQUM5QyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNwQzthQUFNO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzlCO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQVdELDRCQUFXLEdBQVgsVUFBWSxJQUFZLEVBQUUsT0FBZTtRQUF6QyxpQkE4QkM7UUE3QkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNELE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNuQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtnQkFDN0IsT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDckM7WUFDRCxLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQzdCLGFBQWEsRUFDYixFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsUUFBUSxFQUFFLElBQUksTUFBQSxFQUFFLE9BQU8sU0FBQSxFQUFFLEVBQzFDLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxLQUFLLEVBQUU7b0JBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsR0FBRyxLQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMxRSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUFFO3dCQUNwQixNQUFNLENBQUMsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDBCQUEwQixFQUFFLDhDQUE4QyxDQUFDLENBQUMsQ0FBQztxQkFDM0g7eUJBQU07d0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUNqQjtpQkFDSjtxQkFBTTtvQkFDSCxPQUFPLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxHQUFHLEtBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdkUsSUFBTSxRQUFRLEdBQVcsS0FBSSxDQUFDLE1BQU0sQ0FBQztvQkFDckMsS0FBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGVBQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQ3hDLEtBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLEtBQUksQ0FBQztvQkFDMUIsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSSxFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3RKLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLEtBQUksRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNsSyxPQUFPLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUN4QjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBT0QsNkJBQVksR0FBWjtRQUFBLGlCQXlCQztRQXhCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsR0FBRyxLQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0QsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUM3QixjQUFjLEVBQ2QsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLFFBQVEsRUFBRSxFQUMzQixVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLEdBQUcsS0FBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDMUUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTt3QkFDcEIsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQywwQkFBMEIsRUFBRSwrQ0FBK0MsQ0FBQyxDQUFDLENBQUM7cUJBQzVIO3lCQUFNO3dCQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDakI7aUJBQ0o7cUJBQU07b0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsR0FBRyxLQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3pFLElBQU0sUUFBUSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUM7b0JBQzdCLE9BQU8sS0FBSSxDQUFDLE1BQU0sQ0FBQztvQkFDbkIsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSSxFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3RKLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLEtBQUksRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNsSyxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBT0QsK0JBQWMsR0FBZDtRQUNJLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUM1QixDQUFDO0lBS0QsK0JBQWMsR0FBZCxVQUFlLFdBQXdCO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBQ25DLENBQUM7SUFLRCwwQ0FBeUIsR0FBekI7UUFDSSxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBS0QsOEJBQWEsR0FBYjtRQUNJLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUMzQixDQUFDO0lBS0QscUNBQW9CLEdBQXBCO1FBQ0ksT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBS0Qsb0NBQW1CLEdBQW5CLFVBQW9CLEtBQWM7UUFDOUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztJQUNyQyxDQUFDO0lBS0QseUNBQXdCLEdBQXhCLFVBQXlCLGtCQUF5QztRQUM5RCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7SUFDakQsQ0FBQztJQUtELDBCQUFTLEdBQVQ7UUFBQSxpQkFVQztRQVRHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMscUJBQXFCLEVBQUU7aUJBQ3ZCLElBQUksQ0FBQztnQkFDRixPQUFPLEVBQUUsQ0FBQztZQUNkLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLO2dCQUNSLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsQixDQUFDLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELHdCQUFPLEdBQVA7UUFBQSxpQkFzQkM7UUFyQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLDJCQUEyQixFQUFFO2dCQUNsQyxLQUFJLENBQUMsa0JBQWtCLEVBQUU7cUJBQ3BCLElBQUksQ0FBQztvQkFDRixPQUFPLEVBQUUsQ0FBQztnQkFDZCxDQUFDLENBQUM7cUJBQ0QsS0FBSyxDQUFDLFVBQUEsS0FBSztvQkFDUixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQyxDQUFDO2FBQ1Y7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLEVBQUU7b0JBQ3BDLEtBQUksQ0FBQyxPQUFPLEVBQUU7eUJBQ1QsSUFBSSxDQUFDO3dCQUNGLE9BQU8sRUFBRSxDQUFDO29CQUNkLENBQUMsQ0FBQzt5QkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLO3dCQUNSLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbEIsQ0FBQyxDQUFDLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDLENBQUM7YUFDTjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGtDQUFpQixHQUFqQjtRQUNJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsSUFBTSxzQkFBc0IsR0FBWSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQjtnQkFDN0QsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQztZQUNuSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ25EO1FBQ0QsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRTtnQkFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUMzQjtZQUNELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztTQUMzQjtRQUVELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV2QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxvQ0FBb0MsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLGlCQUFpQixDQUFDLENBQUM7SUFDcEosQ0FBQztJQUtELG1DQUFrQixHQUFsQjtRQUNJLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNsQixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7Z0JBQzVDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqQixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQkFDNUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQzNCO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcscUNBQXFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ25KLENBQUM7SUFLRCxnQ0FBZSxHQUFmO1FBQ0ksT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUM7SUFDcEMsQ0FBQztJQUtELDRCQUFXLEdBQVg7UUFDSSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0I7WUFDN0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxJQUFJO1lBQ2hFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssS0FBSyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUtELDRCQUFXLEdBQVg7UUFDSSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0I7WUFDN0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxJQUFJO1lBQ2hFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssS0FBSyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUtELDZCQUFZLEdBQVo7UUFDSSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxLQUFLLFFBQVEsQ0FBQztRQUNsRixJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO1lBQzlCLE1BQU0sR0FBRyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssUUFBUTtnQkFDaEYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDckY7UUFDRCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLElBQUksTUFBTSxDQUFDO0lBQy9DLENBQUM7SUFLRCwwQ0FBeUIsR0FBekI7UUFDSSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNuQixJQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyw4QkFBOEIsSUFBSSxFQUFFLENBQUM7WUFDckcsV0FBVyxDQUFDLFFBQVEsR0FBRyxDQUFDLE9BQU8sV0FBVyxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzlGLFdBQVcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxPQUFPLFdBQVcsQ0FBQyxTQUFTLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xHLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDMUQ7SUFDTCxDQUFDO0lBS0QscUNBQW9CLEdBQXBCO1FBQUEsaUJBY0M7UUFiRyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxFQUFFO1lBQzFDLElBQUksQ0FBQyxrQ0FBa0MsR0FBRyxJQUFJLENBQUM7WUFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFO2dCQUM1QixLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLElBQUksK0NBQXNCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0osQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEVBQUU7WUFDekMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLElBQUksQ0FBQztZQUM5QyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRTtnQkFDcEMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLCtDQUFzQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsS0FBSSxDQUFDLFVBQVUsRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pKLENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBS0QseUNBQXdCLEdBQXhCO1FBQUEsaUJBZ0JDO1FBZkcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQ0FBa0MsRUFBRTtZQUMxQyxJQUFJLENBQUMsa0NBQWtDLEdBQUcsSUFBSSxDQUFDO1lBQy9DLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDOUIsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxJQUFJLCtDQUFzQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsS0FBSSxDQUFDLFVBQVUsRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2SixLQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztTQUNOO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsRUFBRTtZQUN6QyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsSUFBSSxDQUFDO1lBQzlDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUN0QyxLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksK0NBQXNCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JKLEtBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBS0Qsc0NBQXFCLEdBQXJCO1FBQ0ksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLElBQUksQ0FBQyx3QkFBd0IsRUFBRTtnQkFFL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7YUFDNUM7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDeEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO2FBQzNCO1NBQ0o7UUFDRCxJQUFJLENBQUMsa0NBQWtDLEdBQUcsS0FBSyxDQUFDO1FBQ2hELElBQUksQ0FBQyxpQ0FBaUMsR0FBRyxLQUFLLENBQUM7SUFDbkQsQ0FBQztJQUtELHdDQUF1QixHQUF2QjtRQUFBLGlCQVdDO1FBVkcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRTtZQUNoQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLGVBQWUsRUFBRSxVQUFBLFNBQVM7Z0JBQzFDLElBQU0sUUFBUSxHQUFHLEtBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDO2dCQUNqRCxJQUFNLEtBQUssR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxVQUFBLEVBQUUsQ0FBQztnQkFDaEQsS0FBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO2dCQUM1QyxLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLElBQUksdUNBQWtCLENBQUMsS0FBSSxDQUFDLGFBQWEsRUFBRSx5QkFBeUIsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUksQ0FBQyxDQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7SUFLRCw0Q0FBMkIsR0FBM0I7UUFBQSxpQkFZQztRQVhHLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDaEMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQztZQUNyQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsVUFBQSxTQUFTO2dCQUM1QyxJQUFNLFFBQVEsR0FBRyxLQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQztnQkFDakQsSUFBTSxLQUFLLEdBQUcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsVUFBQSxFQUFFLENBQUM7Z0JBQ2hELEtBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztnQkFDNUMsS0FBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7Z0JBQ2hDLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHlCQUF5QixFQUFFLENBQUMsSUFBSSx1Q0FBa0IsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLHlCQUF5QixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1SSxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUtELHlDQUF3QixHQUF4QjtRQUNJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFO2dCQUVwQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQzthQUN6QztpQkFBTTtnQkFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN4QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7YUFDM0I7U0FDSjtRQUNELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQUtELHdCQUFPLEdBQVA7UUFFSSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFLRCx3Q0FBdUIsR0FBdkI7UUFBQSxpQkFNQztRQUxHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsV0FBVyxDQUFDLDJCQUEyQixFQUFFO2lCQUN6QyxJQUFJLENBQUMsVUFBQSxNQUFNLElBQUksT0FBQSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQWYsQ0FBZSxDQUFDO2lCQUMvQixLQUFLLENBQUMsVUFBQSxLQUFLLElBQUksT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QsMENBQXlCLEdBQXpCO1FBQ0ksT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixDQUFDO0lBQ2pELENBQUM7SUFLRCx5Q0FBd0IsR0FBeEI7UUFDSSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUM7SUFDaEQsQ0FBQztJQUlPLG1DQUFrQixHQUExQjtRQUFBLGlCQTRFQztRQTNFRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFFL0IsSUFBTSxvQkFBb0IsR0FBRztnQkFDekIsS0FBSyxFQUFFLEtBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ3pCLEtBQUssRUFBRSxLQUFJLENBQUMsV0FBVyxFQUFFO2FBQzVCLENBQUM7WUFFRixJQUFNLE9BQU8sR0FBRztnQkFDWixXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVc7Z0JBQzdCLGdCQUFnQixFQUFFLG9CQUFvQjtnQkFDdEMsY0FBYyxFQUFFLEtBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxVQUFVLENBQUM7Z0JBQ3RFLFVBQVUsRUFBRSxLQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3BDLFNBQVMsRUFBRSxLQUFLO2FBQ25CLENBQUM7WUFFRixJQUFNLGVBQWUsR0FBRyxVQUFDLGFBQWE7Z0JBQ2xDLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0NBQWtDO3NCQUMxQyxLQUFJLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDO2dCQUVwQyxJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksS0FBSSxDQUFDLFdBQVcsRUFBRSxFQUFFO29CQUNwQixXQUFXLEdBQUcsQ0FBQyxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxZQUFZLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQzNNO2dCQUVELEtBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUU7b0JBQzlDLFFBQVEsRUFBRSxhQUFhO29CQUN2QixVQUFVLEVBQUUsS0FBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLEtBQUs7b0JBQzNDLFFBQVEsRUFBRSxLQUFJLENBQUMsV0FBVyxFQUFFO29CQUM1QixRQUFRLEVBQUUsS0FBSSxDQUFDLFdBQVcsRUFBRTtvQkFDNUIsV0FBVyxFQUFFLEtBQUksQ0FBQyxXQUFXO29CQUM3QixXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVc7b0JBQzdCLFdBQVcsYUFBQTtvQkFDWCxTQUFTLEVBQUUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDakQsZUFBZSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSSxDQUFDLGVBQWUsQ0FBQztvQkFDckQsTUFBTSxFQUFFLEtBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNO2lCQUM3RCxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQ2YsSUFBSSxLQUFLLEVBQUU7d0JBQ1AsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTs0QkFDcEIsTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQywwQkFBMEIsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDLENBQUM7eUJBQ3BIOzZCQUFNOzRCQUNILE1BQU0sQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7eUJBQzdEO3FCQUNKO3lCQUFNO3dCQUNILEtBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDOzZCQUNuRCxJQUFJLENBQUM7NEJBQ0YsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDOzRCQUM1QixLQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7NEJBQ3ZDLEtBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7NEJBQ25DLEtBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDOzRCQUMxQixJQUFJLEtBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRTtnQ0FDeEIsS0FBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7NkJBQzVDOzRCQUNELEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLEVBQUUsQ0FBQyxDQUFDOzRCQUNyRCxLQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7NEJBQ3ZCLE9BQU8sRUFBRSxDQUFDO3dCQUNkLENBQUMsQ0FBQzs2QkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLOzRCQUNSLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDbEIsQ0FBQyxDQUFDLENBQUM7d0JBQ1AsT0FBTyxDQUFDLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO3FCQUNqRTtnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNQLENBQUMsQ0FBQztZQUVGLElBQUksS0FBSSxDQUFDLGVBQWUsRUFBRSxFQUFFO2dCQUN4QixLQUFJLENBQUMsVUFBVSxHQUFHLElBQUksK0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDckQ7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLCtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3JEO1lBQ0QsS0FBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQSxLQUFLO2dCQUN0QyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSztnQkFDVixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxzQ0FBcUIsR0FBN0I7UUFBQSxpQkEwREM7UUF6REcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRS9CLElBQU0sZ0JBQWdCLEdBQUc7Z0JBQ3JCLEtBQUssRUFBRSxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUTtnQkFDdEMsS0FBSyxFQUFFLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRO2FBQ3pDLENBQUM7WUFDRixPQUFPLENBQUMsS0FBSyxDQUFDLHVFQUF1RSxFQUNqRixnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3RCLElBQU0sT0FBTyxHQUFHO2dCQUNaLGNBQWMsRUFBRSxLQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsVUFBVSxDQUFDO2dCQUN0RSxnQkFBZ0IsRUFBRSxnQkFBZ0I7Z0JBQ2xDLFVBQVUsRUFBRSxLQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3BDLFNBQVMsRUFBRSxLQUFLO2FBQ25CLENBQUM7WUFFRixJQUFNLGVBQWUsR0FBRyxVQUFDLGFBQWE7Z0JBQ2xDLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DO3NCQUM1QyxLQUFJLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDO2dCQUNwQyxLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsa0JBQWtCLEVBQUU7b0JBQ2xELE1BQU0sRUFBRSxLQUFJLENBQUMsUUFBUTtvQkFDckIsUUFBUSxFQUFFLGFBQWE7aUJBQzFCLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQkFDZixJQUFJLEtBQUssRUFBRTt3QkFDUCxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQ3pFO3lCQUFNO3dCQUlILElBQUksS0FBSSxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRTs0QkFDeEMsS0FBSSxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsR0FBRyxLQUFLLENBQUM7NEJBQy9DLFVBQVUsQ0FBQztnQ0FHUCxLQUFJLENBQUMsT0FBTyxDQUFDLHFDQUFxQyxHQUFHLEtBQUssQ0FBQzs0QkFDL0QsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO3lCQUNYO3dCQUNELElBQU0sMkJBQTJCLEdBQUcsS0FBSSxDQUFDLE9BQU8sQ0FBQyxxQ0FBcUMsQ0FBQzt3QkFDdkYsS0FBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDLElBQUksQ0FBQzs0QkFDaEYsS0FBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7NEJBQ3pDLEtBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzs0QkFDdkIsT0FBTyxFQUFFLENBQUM7d0JBQ2QsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSzs0QkFDVixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ2xCLENBQUMsQ0FBQyxDQUFDO3FCQUNOO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLCtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELEtBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFO2lCQUMxQixJQUFJLENBQUMsVUFBQSxLQUFLO2dCQUNQLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQixDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUEsS0FBSztnQkFDUixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsK0JBQStCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxrREFBaUMsR0FBekM7UUFDSSxJQUFJLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUV4QixJQUFNLEdBQUcsR0FBUSxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hEO2FBQU07WUFDSCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7WUFDckMsSUFBSSxRQUFRLFNBQWdCLENBQUM7WUFDN0IsS0FBaUIsVUFBaUMsRUFBakMsS0FBQSxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsRUFBakMsY0FBaUMsRUFBakMsSUFBaUMsRUFBRTtnQkFBL0MsUUFBUSxTQUFBO2dCQUNULElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7b0JBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDN0M7YUFDSjtTQUNKO1FBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFdEQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUVwQixJQUFJLElBQUksQ0FBQyxhQUFhLFlBQVksdUJBQVUsRUFBRTtnQkFFMUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDeEMsSUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQWMsSUFBSSxDQUFDLGFBQWMsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFDakYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO2lCQUMxRDtnQkFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN4QyxJQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBYyxJQUFJLENBQUMsYUFBYyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO29CQUNqRixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7aUJBQzFEO2FBQ0o7WUFFRCxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUU7Z0JBQ3pHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2FBQy9CO1NBQ0o7SUFDTCxDQUFDO0lBRU8sZ0NBQWUsR0FBdkI7UUFDSSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBa0J2QyxDQUFDO0lBRU8sZ0NBQWUsR0FBdkI7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUN0QztJQUNMLENBQUM7SUFFTyxrQ0FBaUIsR0FBekI7UUFDSSxJQUFJLFdBQVcsQ0FBQztRQUNoQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLEVBQUU7WUFDMUQsV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDaEYsU0FBUyxDQUFDLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDO1NBQzlEO2FBQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUU7WUFDekMsV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztTQUNsRDthQUFNO1lBQ0gsV0FBVyxHQUFHLFNBQVMsQ0FBQztTQUMzQjtRQUNELE9BQU8sV0FBVyxDQUFDO0lBQ3ZCLENBQUM7SUFFTyxtQ0FBa0IsR0FBMUI7UUFBQSxpQkE4SEM7UUE3SEcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUloQixLQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNLElBQUksT0FBQSxNQUFNLENBQUMsUUFBUSxFQUFFO3FCQUN2RSxJQUFJLENBQ0QsVUFBQSxRQUFRO29CQUNKLFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNO3dCQUVuQixJQUFJLEtBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUU7NEJBRTdCLElBQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQzs0QkFFdkIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7NEJBQ2xDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDOzRCQUM1QyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQzs0QkFHOUIsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGNBQWMsRUFBRTtnQ0FDaEMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7Z0NBQ2xDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO2dDQUMxQyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQ0FDMUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0NBQzVDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO2dDQUdwQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFO29DQUNmLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO2lDQUMxQztxQ0FBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO29DQUMzQixXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztpQ0FDL0M7cUNBQU07b0NBRUgsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7aUNBQzVGO2dDQUVELElBQUksV0FBVyxDQUFDLFdBQVcsQ0FBQyxLQUFLLE9BQU8sRUFBRTtvQ0FDdEMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7aUNBQ3ZEO2dDQUVELFdBQVcsQ0FBQyxhQUFhLENBQUMsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO2dDQUNoRCxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQzs2QkFDL0M7NEJBR0QsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGdCQUFnQixJQUFJLE1BQU0sQ0FBQyxrQkFBa0IsS0FBSyxTQUFTLEVBQUU7Z0NBRTdFLFdBQVcsQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQztnQ0FDMUUsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztnQ0FDakQsV0FBVyxDQUFDLFlBQVksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUM7NkJBQ3BGOzRCQUdELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxvQkFBb0IsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLHFCQUFxQixFQUFFOzZCQUVsRjs0QkFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO3lCQUM1QjtvQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFDUCxDQUFDLENBQUMsRUF2RGlELENBdURqRCxDQUFDLENBQUM7YUFDZjtpQkFBTTtnQkFJSCxLQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQSxRQUFRLElBQUksT0FBQSxRQUFRLENBQUMsUUFBUSxFQUFFO3FCQUM3RSxJQUFJLENBQ0QsVUFBQSxRQUFRO29CQUNKLFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNO3dCQUVuQixJQUFJLEtBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUU7NEJBRTdCLElBQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQzs0QkFFdkIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7NEJBQ2xDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDOzRCQUM1QyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQzs0QkFHOUIsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGFBQWEsRUFBRTtnQ0FDL0IsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7Z0NBQ2xDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO2dDQUMxQyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQ0FDMUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0NBQzVDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO2dDQUdwQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFO29DQUNmLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO2lDQUMxQztxQ0FBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO29DQUMzQixXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztpQ0FDL0M7cUNBQU07b0NBRUgsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7aUNBQzVGO2dDQUVELElBQUksV0FBVyxDQUFDLFdBQVcsQ0FBQyxLQUFLLE9BQU8sRUFBRTtvQ0FDdEMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7aUNBQ3ZEO2dDQUVELFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUM7Z0NBQ3hELFdBQVcsQ0FBQyxhQUFhLENBQUMsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO2dDQUNoRCxXQUFXLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztnQ0FDdEMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7NkJBQ3ZEOzRCQUdELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsSUFBSSxNQUFNLENBQUMsa0JBQWtCLEtBQUssU0FBUyxFQUFFO2dDQUU3RSxXQUFXLENBQUMsMEJBQTBCLENBQUMsR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUM7Z0NBQzFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUM7Z0NBQ2pELFdBQVcsQ0FBQyxZQUFZLENBQUMsR0FBRyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDOzZCQUNwRjs0QkFHRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssb0JBQW9CLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxxQkFBcUIsRUFBRTs2QkFFbEY7NEJBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQzt5QkFDNUI7b0JBQ0wsQ0FBQyxDQUFDLENBQUE7Z0JBQ04sQ0FBQyxDQUFDLEVBeERxRCxDQXdEckQsQ0FDVCxDQUFBO2FBQ0o7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTywrQkFBYyxHQUF0QixVQUF1QixNQUFXO1FBQzlCLE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ25ELE1BQU0sQ0FBQyxJQUFJLEtBQUssY0FBYyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEQsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLGdCQUFnQixJQUFJLE1BQU0sQ0FBQyxTQUFTLElBQUksTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUwsYUFBQztBQUFELENBMTlCQSxBQTA5QkMsSUFBQTtBQTE5Qlksd0JBQU07Ozs7O0FDdEJuQixvRkFBbUY7QUFDbkYsa0ZBQWlGO0FBQ2pGLDZFQUE0RTtBQUU1RSxtREFBc0Q7QUFDdEQsbUNBQXNDO0FBV3RDO0lBMERJLHVCQUFZLE1BQWMsRUFBRSxhQUFvQztRQUFoRSxpQkEyQ0M7UUEzRkQsV0FBTSxHQUF5QixFQUFFLENBQUM7UUE4QmxDLHVDQUFrQyxHQUFHLEtBQUssQ0FBQztRQVEzQyxPQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVdwQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFckMsSUFBSSxDQUFDLENBQUMsYUFBYSxFQUFFO1lBQ2pCLElBQUksTUFBTSxTQUFBLENBQUM7WUFDWCxJQUFJLE9BQU8sYUFBYSxLQUFLLFFBQVEsRUFBRTtnQkFDbkMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDbkQ7aUJBQU0sSUFBSSxhQUFhLFlBQVksV0FBVyxFQUFFO2dCQUM3QyxNQUFNLEdBQUcsYUFBYSxDQUFDO2FBQzFCO1lBRUQsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUNWLElBQUksQ0FBQyxpQkFBaUIsR0FBRztvQkFDckIsYUFBYSxFQUFFLE1BQU07b0JBQ3JCLEtBQUssRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQztvQkFDdEMsRUFBRSxFQUFFLEVBQUU7b0JBQ04sb0JBQW9CLEVBQUUsS0FBSztpQkFDOUIsQ0FBQztnQkFDRixJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO29CQUM1QixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7aUJBQ3BFO2dCQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDO2dCQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQzthQUN6QjtTQUNKO1FBRUQsSUFBSSxDQUFDLGVBQWUsR0FBRztZQUNuQixJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3ZCLElBQUksQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFO29CQUNoQyxPQUFPLENBQUMsSUFBSSxDQUFDLCtCQUErQixHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLHdCQUF3QixDQUFDLENBQUM7b0JBQ2hHLEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDLElBQUkscUNBQWlCLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDMUc7cUJBQU07b0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxDQUFDO29CQUNyRyxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLElBQUkscUNBQWlCLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUN0SDthQUNKO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsd0JBQXdCLENBQUMsQ0FBQztnQkFDNUYsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzFHO1lBQ0QsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx1Q0FBa0IsQ0FBQyxLQUFJLEVBQUUsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRyxDQUFDLENBQUM7SUFDTixDQUFDO0lBS0QsMEJBQUUsR0FBRixVQUFHLElBQVksRUFBRSxPQUErQjtRQUFoRCxpQkE2QkM7UUE1QkcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFVBQUEsS0FBSztZQUNsQixJQUFJLEtBQUssRUFBRTtnQkFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsa0JBQWtCLEdBQUcsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNqSDtpQkFBTTtnQkFDSCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsa0JBQWtCLEdBQUcsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2FBQzFHO1lBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxJQUFJLEtBQUsscUJBQXFCLEVBQUU7WUFDaEMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsa0NBQWtDLEVBQUU7Z0JBQzFELElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JILElBQUksQ0FBQyxrQ0FBa0MsR0FBRyxLQUFLLENBQUM7YUFDbkQ7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLGVBQWUsSUFBSSxJQUFJLEtBQUssY0FBYyxFQUFFO1lBQ3JELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUs7Z0JBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSztnQkFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEtBQUs7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsS0FBSyxDQUFDLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUksdUNBQWtCLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDLElBQUkscUNBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMxRztTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUsseUJBQXlCLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7WUFDNUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1NBQ3pDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUtELDRCQUFJLEdBQUosVUFBSyxJQUFZLEVBQUUsT0FBK0I7UUFDOUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFVBQUEsS0FBSztZQUNwQixJQUFJLEtBQUssRUFBRTtnQkFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDOUQ7aUJBQU07Z0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLGtCQUFrQixDQUFDLENBQUM7YUFDdkQ7WUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLElBQUksS0FBSyxxQkFBcUIsRUFBRTtZQUNoQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxrQ0FBa0MsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLHFDQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4SDtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssZUFBZSxJQUFJLElBQUksS0FBSyxjQUFjLEVBQUU7WUFDckQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLO2dCQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUssS0FBSztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRTtnQkFDdkMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx1Q0FBa0IsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDL0YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzFHO1NBQ0o7UUFDRCxJQUFJLElBQUksS0FBSyx5QkFBeUIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtZQUM1RCxJQUFJLENBQUMsTUFBTSxDQUFDLDJCQUEyQixFQUFFLENBQUM7U0FDN0M7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBS0QsMkJBQUcsR0FBSCxVQUFJLElBQVksRUFBRSxPQUFnQztRQUM5QyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNwQzthQUFNO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzlCO1FBRUQsSUFBSSxJQUFJLEtBQUsseUJBQXlCLEVBQUU7WUFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1NBQzFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQWFELHVDQUFlLEdBQWYsVUFBZ0IsS0FBdUI7UUFFbkMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFO1lBQ3hELElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFO2dCQUNsRCxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDbEQ7U0FDSjtRQUdELEtBQWdCLFVBQVcsRUFBWCxLQUFBLElBQUksQ0FBQyxNQUFNLEVBQVgsY0FBVyxFQUFYLElBQVcsRUFBRTtZQUF4QixJQUFNLENBQUMsU0FBQTtZQUNSLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7Z0JBQ25CLE9BQU8sQ0FBQyxDQUFDO2FBQ1o7U0FDSjtRQUVELElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztRQUVyQixLQUE0QixVQUFrQyxFQUFsQyxLQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBbEMsY0FBa0MsRUFBbEMsSUFBa0MsRUFBRTtZQUEzRCxJQUFNLGFBQWEsU0FBQTtZQUNwQixJQUFJLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDeEMsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixNQUFNO2FBQ1Q7U0FDSjtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsVUFBQSxhQUFhO1lBQ3BELGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx5QkFBeUIsQ0FBQztZQUMzQixLQUFLLE9BQUE7WUFDTCxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7WUFDWixvQkFBb0IsRUFBRSxLQUFLO1NBQzlCLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFdkQsT0FBTyxZQUFZLENBQUM7SUFDeEIsQ0FBQztJQWNELDBDQUFrQixHQUFsQixVQUFtQixhQUFvQyxFQUFFLFVBQTRCO1FBQ2pGLElBQUksTUFBTSxDQUFDO1FBQ1gsSUFBSSxPQUFPLGFBQWEsS0FBSyxRQUFRLEVBQUU7WUFDbkMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDVCxNQUFNLElBQUksS0FBSyxDQUFDLHlFQUF5RSxHQUFHLGFBQWEsQ0FBQyxDQUFDO2FBQzlHO1NBQ0o7YUFBTSxJQUFJLGFBQWEsWUFBWSxXQUFXLEVBQUU7WUFDN0MsTUFBTSxHQUFHLGFBQWEsQ0FBQztTQUMxQjthQUFNO1lBQ0gsTUFBTSxJQUFJLEtBQUssQ0FBQyx5RUFBeUUsR0FBRyxhQUFhLENBQUMsQ0FBQztTQUM5RztRQUVELElBQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUNBQWUsQ0FBQyxNQUFNLENBQUM7UUFDakUsUUFBUSxPQUFPLEVBQUU7WUFDYixLQUFLLGlDQUFlLENBQUMsS0FBSztnQkFDdEIsTUFBTSxDQUFDLFVBQVksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDNUQsTUFBTTtZQUNWLEtBQUssaUNBQWUsQ0FBQyxNQUFNO2dCQUN2QixNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixNQUFNO1lBQ1YsS0FBSyxpQ0FBZSxDQUFDLE1BQU07Z0JBQ3ZCLE1BQU0sQ0FBQyxVQUFZLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDaEQsTUFBTTtZQUNWLEtBQUssaUNBQWUsQ0FBQyxPQUFPO2dCQUN4QixNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELE1BQU07WUFDVixLQUFLLGlDQUFlLENBQUMsT0FBTztnQkFDeEIsTUFBTSxDQUFDLFVBQVksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNoRCxNQUFNO1lBQ1Y7Z0JBQ0ksT0FBTyxHQUFHLGlDQUFlLENBQUMsTUFBTSxDQUFDO2dCQUNqQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixNQUFNO1NBQ2I7UUFFRCxJQUFNLENBQUMsR0FBdUI7WUFDMUIsYUFBYSxFQUFFLE1BQU07WUFDckIsS0FBSyxPQUFBO1lBQ0wsVUFBVSxFQUFFLE9BQU87WUFDbkIsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ1osb0JBQW9CLEVBQUUsS0FBSztTQUM5QixDQUFDO1FBQ0YsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxDLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUMsSUFBSSxxQ0FBaUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RyxJQUFJLENBQUMsa0NBQWtDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUVuRSxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBS0QsaURBQXlCLEdBQXpCLFVBQTBCLEtBQXVCO1FBQzdDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxFQUFFO1lBRTNELElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFO2dCQUVsRCxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDbEQ7U0FDSjtRQUNELEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLEtBQUssQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBRXZCLElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7WUFDNUIsS0FBSyxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDN0M7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUNYLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUVsRixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO2FBQ3RCO1NBQ0o7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDaEQsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbkIsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsS0FBSyxpQkFBaUIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFO2dCQUUzRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDakM7aUJBQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUU7Z0JBQ2pHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDM0I7U0FDSjtJQUNMLENBQUM7SUFLRCx1Q0FBZSxHQUFmO1FBQUEsaUJBc0JDO1FBckJHLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRTtZQUNyRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ25EO1NBQ0o7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFBLGtCQUFrQjtZQUVsQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLEtBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RSxrQkFBa0IsQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFDaEQsSUFBSSxDQUFDLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFO2dCQUdwQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDM0UsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLHFDQUFpQixDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDaEk7WUFFRCxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUUxQyxLQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBaEIsQ0FBZ0IsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELHlDQUFpQixHQUFqQixVQUFrQixLQUF1QjtRQUNyQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3pDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO2dCQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUMxRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pCLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3hELE1BQU07YUFDVDtTQUNKO1FBQ0QsT0FBTyxhQUFhLENBQUM7SUFDekIsQ0FBQztJQUtELGdEQUF3QixHQUF4QjtRQUNJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsRUFBRTtZQUMxRixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztJQUtELHlDQUFpQixHQUFqQixVQUFrQixXQUF3QjtRQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFBLGtCQUFrQjtZQUNsQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQztZQUNqRCxJQUFJLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFHeEIsSUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztnQkFDdkQsSUFBTSxRQUFRLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDO2dCQUMxQyxPQUFTLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDM0Qsa0JBQWtCLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQzthQUN2QztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGlDQUFTLEdBQVQsVUFBVSxJQUFZLEVBQUUsVUFBaUI7UUFDckMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFTyxpREFBeUIsR0FBakMsVUFBa0Msa0JBQXNDO1FBQ3BFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDaEMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDakQ7SUFDTCxDQUFDO0lBRU8sbUNBQVcsR0FBbkIsVUFBb0IsS0FBSztRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQ3pCLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLGlCQUFpQixDQUFDO1lBQzFDLEtBQUssQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLGlCQUFpQixDQUFDO1NBQ25EO0lBQ0wsQ0FBQztJQUVPLHlDQUFpQixHQUF6QixVQUEwQixLQUFLO1FBQzNCLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNoQyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7SUFDMUMsQ0FBQztJQUVMLG9CQUFDO0FBQUQsQ0F4YkEsQUF3YkMsSUFBQTtBQXhiWSxzQ0FBYTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDbkIxQixpREFBZ0Q7QUFPaEQ7SUFBZ0MsOEJBQWE7SUFVekMsb0JBQVksTUFBYyxFQUFFLE1BQTRCLEVBQUUsVUFBZ0M7UUFBMUYsWUFDSSxrQkFBTSxNQUFNLEVBQUUsTUFBTSxDQUFDLFNBSXhCO1FBSEcsS0FBSSxDQUFDLE9BQU8sR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDO1FBQ2xDLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDOztJQUNqQyxDQUFDO0lBTUQscUNBQWdCLEdBQWhCLFVBQWlCLEtBQWM7UUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLO1lBQ3hELEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLENBQUM7UUFDMUcsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQU1ELHFDQUFnQixHQUFoQixVQUFpQixLQUFjO1FBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUN4RCxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzFHLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTCxpQkFBQztBQUFELENBekNBLEFBeUNDLENBekMrQiw2QkFBYSxHQXlDNUM7QUF6Q1ksZ0NBQVU7Ozs7O0FDUnZCLElBQVksa0JBS1g7QUFMRCxXQUFZLGtCQUFrQjtJQUMxQixxQ0FBZSxDQUFBO0lBQ2YsNkNBQXVCLENBQUE7SUFDdkIsdUNBQWlCLENBQUE7SUFDakIsMkNBQXFCLENBQUE7QUFDekIsQ0FBQyxFQUxXLGtCQUFrQixHQUFsQiwwQkFBa0IsS0FBbEIsMEJBQWtCLFFBSzdCOzs7OztBQ0ZELElBQVksaUJBcUZYO0FBckZELFdBQVksaUJBQWlCO0lBTXpCLG9FQUErQyxDQUFBO0lBTS9DLGtFQUE2QyxDQUFBO0lBTzdDLG9FQUErQyxDQUFBO0lBTS9DLG9FQUErQyxDQUFBO0lBTS9DLGtGQUE2RCxDQUFBO0lBTTdELHNGQUFpRSxDQUFBO0lBTWpFLDRFQUF1RCxDQUFBO0lBTXZELGtGQUE2RCxDQUFBO0lBTTdELGtGQUE2RCxDQUFBO0lBTTdELGdFQUEyQyxDQUFBO0lBTzNDLDhFQUF5RCxDQUFBO0lBTXpELDhFQUF5RCxDQUFBO0lBS3pELHNFQUFpRCxDQUFBO0lBS2pELG9EQUErQixDQUFBO0FBQ25DLENBQUMsRUFyRlcsaUJBQWlCLEdBQWpCLHlCQUFpQixLQUFqQix5QkFBaUIsUUFxRjVCO0FBS0Q7SUFRSSx1QkFBWSxJQUF1QixFQUFFLE9BQWU7UUFDaEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQUVMLG9CQUFDO0FBQUQsQ0FiQSxBQWFDLElBQUE7QUFiWSxzQ0FBYTs7Ozs7QUMxRjFCLElBQVksZUF1Qlg7QUF2QkQsV0FBWSxlQUFlO0lBS3ZCLGtDQUFlLENBQUE7SUFJZixvQ0FBaUIsQ0FBQTtJQUlqQixvQ0FBaUIsQ0FBQTtJQUlqQixzQ0FBbUIsQ0FBQTtJQUluQixzQ0FBbUIsQ0FBQTtBQUV2QixDQUFDLEVBdkJXLGVBQWUsR0FBZix1QkFBZSxLQUFmLHVCQUFlLFFBdUIxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUJELGlDQUFnQztBQVVoQztJQUFxQyxtQ0FBSztJQXNCdEMseUJBQVksVUFBbUIsRUFBRSxNQUFlLEVBQUUsSUFBWSxFQUFFLFVBQXNCLEVBQUUsTUFBYztRQUF0RyxZQUNJLGtCQUFNLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBR2xDO1FBRkcsS0FBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7O0lBQ3pCLENBQUM7SUFNRCw2Q0FBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUU3QixzQkFBQztBQUFELENBbENBLEFBa0NDLENBbENvQyxhQUFLLEdBa0N6QztBQWxDWSwwQ0FBZTs7Ozs7QUNMNUI7SUF5QkksZUFBWSxVQUFtQixFQUFFLE1BQXdDLEVBQUUsSUFBWTtRQUx2RixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFNckIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDckIsQ0FBQztJQUtELGtDQUFrQixHQUFsQjtRQUNJLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO0lBQ2pDLENBQUM7SUFnQkQsOEJBQWMsR0FBZDtRQUVJLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxjQUFRLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0lBQ2pDLENBQUM7SUFPTCxZQUFDO0FBQUQsQ0EvREEsQUErREMsSUFBQTtBQS9EcUIsc0JBQUs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0wzQixpQ0FBZ0M7QUFRaEM7SUFBaUMsK0JBQUs7SUFVbEMscUJBQVksTUFBYyxFQUFFLFNBQWlCLEVBQUUsSUFBWTtRQUEzRCxZQUNJLGtCQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLFNBRWxDO1FBREcsS0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7O0lBQ3JCLENBQUM7SUFNRCx5Q0FBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUU3QixrQkFBQztBQUFELENBckJBLEFBcUJDLENBckJnQyxhQUFLLEdBcUJyQztBQXJCWSxrQ0FBVzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDUnhCLGlDQUFnQztBQWdCaEM7SUFBNEMsMENBQUs7SUFlN0MsZ0NBQVksTUFBZSxFQUFFLElBQVksRUFBRSxVQUFzQixFQUFFLFFBQWdCO1FBQW5GLFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FJN0I7UUFIRyxLQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixLQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixLQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7SUFDN0IsQ0FBQztJQU1ELG9EQUFtQixHQUFuQixjQUF3QixDQUFDO0lBRTdCLDZCQUFDO0FBQUQsQ0E1QkEsQUE0QkMsQ0E1QjJDLGFBQUssR0E0QmhEO0FBNUJZLHdEQUFzQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDaEJuQyxpQ0FBZ0M7QUFTaEM7SUFBb0Msa0NBQUs7SUErQnJDLHdCQUFZLE1BQWUsRUFBRSxJQUFZLEVBQUUsRUFBVSxFQUFFLElBQVksRUFBRSxNQUFlO1FBQXBGLFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FNN0I7UUFMRyxLQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksSUFBSSxLQUFLLEVBQUUsRUFBRTtZQUNiLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1NBQ3BCO1FBQ0QsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7O0lBQ3pCLENBQUM7SUFNRCw0Q0FBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUU3QixxQkFBQztBQUFELENBOUNBLEFBOENDLENBOUNtQyxhQUFLLEdBOEN4QztBQTlDWSx3Q0FBYzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDVDNCLGlDQUFnQztBQU9oQztJQUE4Qyw0Q0FBSztJQWMvQyxrQ0FBWSxNQUFlLEVBQUUsTUFBYztRQUEzQyxZQUNJLGtCQUFNLElBQUksRUFBRSxNQUFNLEVBQUUscUJBQXFCLENBQUMsU0FFN0M7UUFERyxLQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzs7SUFDekIsQ0FBQztJQUtELHNEQUFtQixHQUFuQjtRQUVJLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxpQ0FBaUMsQ0FBQyxDQUFDO1FBRWhHLElBQU0sT0FBTyxHQUFZLElBQUksQ0FBQyxNQUFNLENBQUM7UUFHckMsS0FBSyxJQUFNLFlBQVksSUFBSSxPQUFPLENBQUMsaUJBQWlCLEVBQUU7WUFDbEQsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sRUFBRTtnQkFDbEQsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUNuRSxPQUFPLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQ3BFLElBQUksT0FBTyxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUU7b0JBQzlELE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO2lCQUNsRjtnQkFDRCxPQUFPLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM3RixPQUFPLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDckQ7WUFDRCxPQUFPLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNsRDtJQUNMLENBQUM7SUFFTCwrQkFBQztBQUFELENBM0NBLEFBMkNDLENBM0M2QyxhQUFLLEdBMkNsRDtBQTNDWSw0REFBd0I7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1ByQyxpQ0FBZ0M7QUFVaEM7SUFBaUMsK0JBQUs7SUF3QmxDLHFCQUFZLE1BQWUsRUFBRSxJQUFZLEVBQUUsSUFBWSxFQUFFLElBQWdCO1FBQXpFLFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FJN0I7UUFIRyxLQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixLQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixLQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQzs7SUFDckIsQ0FBQztJQU1ELHlDQUFtQixHQUFuQixjQUF3QixDQUFDO0lBRTdCLGtCQUFDO0FBQUQsQ0FyQ0EsQUFxQ0MsQ0FyQ2dDLGFBQUssR0FxQ3JDO0FBckNZLGtDQUFXOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNWeEIsaUNBQWdDO0FBQ2hDLHNEQUFxRDtBQUNyRCxrREFBaUQ7QUFTakQ7SUFBaUMsK0JBQUs7SUEwQmxDLHFCQUFZLFVBQW1CLEVBQUUsTUFBMkIsRUFBRSxJQUFZLEVBQUUsTUFBYyxFQUFFLE1BQWM7UUFBMUcsWUFDSSxrQkFBTSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUdsQztRQUZHLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztJQUN6QixDQUFDO0lBS0QseUNBQW1CLEdBQW5CO1FBQ0ksSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLGlCQUFpQixFQUFFO1lBRWpDLElBQUksSUFBSSxDQUFDLE1BQU0sWUFBWSxpQkFBTyxFQUFFO2dCQUVoQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsaUNBQWlDLENBQUMsQ0FBQztnQkFDaEcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2FBQ25DO2lCQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sWUFBWSxxQkFBUyxFQUFFO2dCQUV6QyxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsbUNBQW1DLENBQUMsQ0FBQztnQkFDbEcsYUFBYSxDQUFhLElBQUksQ0FBQyxNQUFPLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxLQUFLLENBQUM7Z0JBR2hELElBQU0sa0JBQWtCLEdBQWUsSUFBSSxDQUFDLE1BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO2dCQUN4RSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUNoRCxJQUFJLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFpQixJQUFJLENBQUMsTUFBTyxFQUFFO3dCQUNwRCxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUNoQyxNQUFNO3FCQUNUO2lCQUNKO2FBQ0o7WUFHRCxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFJakMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWE7Z0JBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7WUFHM0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBR3RFLElBQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDcEcsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRTtnQkFDbEQsSUFBTSxtQkFBbUIsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO2dCQUM3RCxLQUFLLElBQUksQ0FBQyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRTtvQkFDdEQsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7d0JBQ3BELG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7cUJBQ3BDO2lCQUNKO2FBQ0o7U0FFSjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBbEZBLEFBa0ZDLENBbEZnQyxhQUFLLEdBa0ZyQztBQWxGWSxrQ0FBVzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDWHhCLGlDQUFnQztBQVdoQztJQUF3QyxzQ0FBSztJQWN6Qyw0QkFBWSxNQUFxQixFQUFFLElBQVksRUFBRSxLQUF5QjtRQUExRSxZQUNJLGtCQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBRTdCO1FBREcsS0FBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7O0lBQ3ZCLENBQUM7SUFNRCxnREFBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUU3Qix5QkFBQztBQUFELENBekJBLEFBeUJDLENBekJ1QyxhQUFLLEdBeUI1QztBQXpCWSxnREFBa0I7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1gvQixpQ0FBZ0M7QUFVaEM7SUFBZ0QsOENBQUs7SUFpQ2pELG9DQUFZLE1BQStCLEVBQUUsTUFBYyxFQUFFLGVBQXVCLEVBQUUsUUFBZ0IsRUFBRSxRQUFnQixFQUFFLE1BQWM7UUFBeEksWUFDSSxrQkFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLHVCQUF1QixDQUFDLFNBTWhEO1FBTEcsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsS0FBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7UUFDdkMsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7O0lBQ3pCLENBQUM7SUFNRCx3REFBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUU3QixpQ0FBQztBQUFELENBaERBLEFBZ0RDLENBaEQrQyxhQUFLLEdBZ0RwRDtBQWhEWSxnRUFBMEI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1Z2QyxpQ0FBZ0M7QUFVaEM7SUFBdUMscUNBQUs7SUFVeEMsMkJBQVksT0FBeUIsRUFBRSxNQUFxQixFQUFFLElBQVk7UUFBMUUsWUFDSSxrQkFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUU3QjtRQURHLEtBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDOztJQUMzQixDQUFDO0lBTUQsK0NBQW1CLEdBQW5CLGNBQXdCLENBQUM7SUFFN0Isd0JBQUM7QUFBRCxDQXJCQSxBQXFCQyxDQXJCc0MsYUFBSyxHQXFCM0M7QUFyQlksOENBQWlCOzs7QUMzQjlCLFNBQVMsTUFBTTtJQUViLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUdqQixJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVMsUUFBUTtRQUU5QixLQUFJLElBQUksR0FBRyxJQUFJLE9BQU8sRUFDdEI7WUFDRSxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFMUIsS0FBSSxJQUFJLElBQUksSUFBSSxNQUFNO2dCQUNwQixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDMUI7UUFBQSxDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLEdBQUcsR0FBRyxVQUFTLEVBQUUsRUFBRSxNQUFNO1FBRTVCLElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQixJQUFHLEdBQUcsSUFBSSxTQUFTO1lBQ2pCLE9BQU8sU0FBUyxDQUFDO1FBRW5CLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2pCLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBUyxFQUFFLEVBQUUsTUFBTTtRQUUvQixJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUIsSUFBRyxHQUFHLElBQUksU0FBUztZQUNqQixPQUFPO1FBRVQsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFHZixLQUFJLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBQztZQUFDLE9BQU8sS0FBSyxDQUFBO1NBQUM7UUFFL0IsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDekIsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLEdBQUcsR0FBRyxVQUFTLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTTtRQUVuQyxJQUFHLEtBQUssSUFBSSxTQUFTO1lBQ25CLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFakMsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFCLElBQUcsR0FBRyxJQUFJLFNBQVM7WUFDakIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFFN0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUNsQixDQUFDLENBQUM7QUFDSixDQUFDO0FBQUEsQ0FBQztBQUdGLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxHQUFHLFVBQVMsRUFBRSxFQUFFLE1BQU07SUFFeEMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDakMsSUFBRyxLQUFLLElBQUksU0FBUztRQUNuQixPQUFPLFNBQVMsQ0FBQztJQUVuQixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUV4QixPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUdGLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDOzs7QUNoRHhCLElBQUksYUFBYSxHQUFJLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBR2hELE9BQU8sQ0FBQyxhQUFhLEdBQUksYUFBYSxDQUFDOzs7QUNIdkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2hDLElBQUkseUJBQXlCLEdBQUcsT0FBTyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7QUFFbEYsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxJQUFJO0lBQ25CLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQztBQUNyQixDQUFDLENBQUM7QUFFRixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFFekIsSUFBSSxZQUFZLEdBQUcsY0FBYyxDQUFDO0FBQ2xDLElBQUksU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUM1QixJQUFJLFlBQVksR0FBRyxjQUFjLENBQUM7QUFFbEMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBdUJyQixTQUFTLGFBQWEsQ0FBQyxhQUFhO0lBRWhDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztJQUVoQixJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsRUFBRSxDQUFDO0lBRWhDLElBQUkseUJBQXlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFbkMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQztJQUN4QixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDNUIsSUFBSSxZQUFZLENBQUM7SUFFakIsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDO0lBRTFCLElBQUksY0FBYyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUM7SUFDN0MsSUFBSSxhQUFhLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQztJQUMzQyxJQUFJLFdBQVcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO0lBQ3ZDLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFFL0IsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsVUFBVSxNQUFNLEVBQUUsT0FBTztRQUM5QyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUE7SUFFRCxRQUFRLENBQUMsY0FBYyxHQUFHO1FBQ3RCLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUNyRCxJQUFJLE1BQU0sS0FBSyxZQUFZLEVBQUU7WUFDekIsTUFBTSxDQUFDLEtBQUssQ0FBQyxrR0FBa0csQ0FBQyxDQUFDO1lBQ2pILE9BQU87U0FDVjtRQUVELFFBQVEsRUFBRSxDQUFDO1FBRVgsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUN0QixJQUFJLGNBQWMsRUFBRTtZQUNoQixjQUFjLEVBQUUsQ0FBQztTQUNwQjtJQUNMLENBQUMsQ0FBQTtJQUVELFFBQVEsQ0FBQyxhQUFhLEdBQUc7UUFDckIsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3BELElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUN0QixNQUFNLENBQUMsS0FBSyxDQUFDLDhGQUE4RixDQUFDLENBQUM7WUFDN0csT0FBTztTQUNWO1FBQ0QsTUFBTSxHQUFHLFNBQVMsQ0FBQztRQUVuQiw0QkFBNEIsRUFBRSxDQUFDO1FBRS9CLElBQUksYUFBYSxFQUFFO1lBQ2YsYUFBYSxFQUFFLENBQUM7U0FDbkI7SUFDTCxDQUFDLENBQUE7SUFFRCxRQUFRLENBQUMsV0FBVyxHQUFHO1FBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUNsRCxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUU7WUFDdEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw0RkFBNEYsQ0FBQyxDQUFDO1lBQzNHLE9BQU87U0FDVjtRQUNELE1BQU0sR0FBRyxTQUFTLENBQUM7UUFFbkIsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixPQUFPLEVBQUUsQ0FBQztRQUVWLElBQUksV0FBVyxFQUFFO1lBQ2IsV0FBVyxFQUFFLENBQUM7U0FDakI7SUFDTCxDQUFDLENBQUE7SUFFRCxRQUFRLENBQUMsT0FBTyxHQUFHLFVBQVUsS0FBSztRQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFFOUMsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUV0QixRQUFRLEVBQUUsQ0FBQztRQUVYLElBQUksT0FBTyxFQUFFO1lBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2xCO0lBQ0wsQ0FBQyxDQUFBO0lBRUQsSUFBSSxFQUFFLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVqRCxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUU3RCxJQUFJLGlCQUFpQixHQUFHO1FBQ3BCLGVBQWUsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLGNBQWM7UUFDakQsb0JBQW9CLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUI7S0FDbEUsQ0FBQztJQUVGLElBQUksR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFDdEUsVUFBVSxPQUFPO1FBRWIsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFN0QsSUFBSTtZQUNBLElBQUksSUFBSSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRTdDLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtnQkFDcEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRywyQkFBMkIsQ0FBQyxDQUFDO2FBQzFFO2lCQUFNO2dCQUNILElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQ2pDO1NBQ0o7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNWLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDckI7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVQLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVE7UUFDMUMsSUFBSSxNQUFNLEtBQUssTUFBTSxFQUFFO1lBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEdBQUcsTUFBTSxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7U0FDbkY7UUFFRCxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFN0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsS0FBSyxFQUFFLE1BQU07WUFDOUMsSUFBSSxLQUFLLEVBQUU7Z0JBQ1AsSUFBSTtvQkFDQSxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsT0FBTyxHQUFHLHNCQUFzQjt3QkFDMUQsTUFBTSxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLFdBQVc7d0JBQzFELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkIsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO3dCQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7cUJBQzVEO2lCQUNKO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUU7Z0JBQ2QsS0FBSyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7YUFDbkM7WUFDRCxJQUFJLFFBQVEsRUFBRTtnQkFDVixJQUFJLE1BQU0sSUFBSSxTQUFTLElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxNQUFNLEVBQUU7b0JBQ2hELE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztpQkFDdkQ7Z0JBQ0QsUUFBUSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQzthQUMzQjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFBO0lBRUQsU0FBUyw0QkFBNEI7UUFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsR0FBRyxXQUFXLEdBQUcsUUFBUTtZQUNoRSx5QkFBeUIsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNyQyx5QkFBeUIsR0FBRyxXQUFXLENBQUM7SUFDNUMsQ0FBQztJQUVELFNBQVMsUUFBUTtRQUNiLElBQUksWUFBWSxFQUFFO1lBQ2QsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ2xCLElBQUksV0FBVyxJQUFJLENBQUMsSUFBSSxXQUFXLElBQUkseUJBQXlCLEVBQUU7Z0JBQzlELE1BQU0sR0FBRztvQkFDTCxRQUFRLEVBQUUsYUFBYSxDQUFDLFNBQVMsSUFBSSxhQUFhO2lCQUNyRCxDQUFDO2FBQ0w7WUFDRCxXQUFXLEVBQUUsQ0FBQztZQUVkLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLFVBQVUsT0FBTztnQkFDeEMsT0FBTyxVQUFVLEtBQUssRUFBRSxNQUFNO29CQUMxQixJQUFJLEtBQUssRUFBRTt3QkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixHQUFHLE9BQU8sR0FBRyxJQUFJOzRCQUNuRCxLQUFLLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDO3dCQUN6QixJQUFJLE9BQU8sR0FBRyx5QkFBeUIsRUFBRTs0QkFDckMsWUFBWSxHQUFHLEtBQUssQ0FBQzs0QkFDckIsNEJBQTRCLEVBQUUsQ0FBQzs0QkFDL0IsTUFBTSxDQUFDLEtBQUssQ0FBQywwQ0FBMEM7Z0NBQ25ELE9BQU8sR0FBRyxvQkFBb0IsQ0FBQyxDQUFDOzRCQUNwQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7eUJBQ3BCO3FCQUNKO2dCQUNMLENBQUMsQ0FBQTtZQUNMLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7U0FDcEI7YUFBTTtZQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztTQUNoRTtJQUNMLENBQUM7SUFNRCxTQUFTLE9BQU87UUFDWixJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ2xCLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQTtZQUM3QyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBRXZCLElBQUksYUFBYSxDQUFDLFNBQVMsSUFBSSxTQUFTLEVBQUU7Z0JBQ3RDLFlBQVksR0FBRyxXQUFXLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDOUQsUUFBUSxFQUFFLENBQUM7YUFDZDtTQUNKO0lBQ0wsQ0FBQztJQUVELFNBQVMsUUFBUTtRQUNiLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM1QixlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLElBQUksRUFBRSxNQUFNO1FBQy9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxHQUFHLFlBQVksR0FBRyxNQUFNLENBQUMsQ0FBQztRQUVwRSxJQUFJLFlBQVksSUFBSSxTQUFTLEVBQUU7WUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ3ZDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUMvQjtRQUNELGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDeEIsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUVyQixJQUFJLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRTtZQUNoQyxNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUE7WUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLFVBQVUsS0FBSyxFQUFFLE1BQU07Z0JBQ25ELElBQUksS0FBSyxFQUFFO29CQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2lCQUN6RTtnQkFDRCxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMzQixDQUFDLENBQUMsQ0FBQztTQUNOO2FBQU07WUFDSCxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztTQUMxQjtJQUNMLENBQUMsQ0FBQTtJQUdELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxNQUFNO1FBQzlCLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUIsQ0FBQyxDQUFBO0lBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRztRQUNiLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDLENBQUE7SUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHO1FBQ2IsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLE9BQU8sRUFBRSxDQUFDO0lBQ2QsQ0FBQyxDQUFBO0FBQ0wsQ0FBQztBQUdELE1BQU0sQ0FBQyxPQUFPLEdBQUcsYUFBYSxDQUFDOzs7QUNsUi9CLElBQUkseUJBQXlCLEdBQUksT0FBTyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFHeEUsT0FBTyxDQUFDLHlCQUF5QixHQUFJLHlCQUF5QixDQUFDOzs7O0FDSi9ELFlBQVksQ0FBQztBQUViLElBQUksZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDO0FBRS9ELElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQztBQWlCckIsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQztBQUV6QixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDbkIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQVlmLFNBQVMseUJBQXlCLENBQUMsTUFBTTtJQUVyQyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDcEIsSUFBSSxzQkFBc0IsQ0FBQztJQUMzQixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO0lBQ3ZCLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDakMsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRXpCLElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0lBRWpDLElBQUksRUFBRSxDQUFDO0lBRVAsSUFBSSxTQUFTLEVBQUU7UUFDWCxFQUFFLEdBQUcsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDMUI7U0FBTTtRQUNILEVBQUUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUM3QjtJQUVELEVBQUUsQ0FBQyxNQUFNLEdBQUc7UUFDUixZQUFZLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLElBQUksTUFBTSxDQUFDLFdBQVcsRUFBRTtZQUNwQixNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDeEI7SUFDTCxDQUFDLENBQUM7SUFFRixFQUFFLENBQUMsT0FBTyxHQUFHLFVBQVUsS0FBSztRQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixHQUFHLEtBQUssR0FBRyxnQ0FBZ0MsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4RixJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDaEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QjtJQUNMLENBQUMsQ0FBQztJQUVGLFNBQVMsWUFBWSxDQUFDLEVBQUUsRUFBRSxLQUFLO1FBQzNCLElBQUk7WUFDQSxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixHQUFHLEtBQUssQ0FBQyxDQUFDO1NBQ25EO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDUixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ25CO0lBQ0wsQ0FBQztJQUVELElBQUksbUJBQW1CLEdBQUc7UUFDdEIsSUFBSSxFQUFFLENBQUMsVUFBVSxLQUFLLE1BQU0sRUFBRTtZQUMxQixJQUFJLE9BQU8sRUFBRTtnQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7YUFDN0M7aUJBQU07Z0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO2dCQUNoRSxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDdEM7U0FDSjthQUFNO1lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1NBQ3ZFO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsRUFBRSxDQUFDLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQztJQUVqQyxTQUFTLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxVQUFVO1FBQzlDLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLEdBQUcsVUFBVSxHQUFHLFFBQVEsR0FBRyxVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFekYsSUFBSSxVQUFVLEtBQUssQ0FBQyxFQUFFO1lBQ2xCLElBQUksWUFBWSxFQUFFO2dCQUNkLE1BQU0sQ0FBQyxJQUFJLENBQUMsOEVBQThFLENBQUMsQ0FBQTtnQkFDM0YsT0FBTzthQUNWO2lCQUFNO2dCQUNILFlBQVksR0FBRyxJQUFJLENBQUM7YUFDdkI7WUFFRCxJQUFJLE1BQU0sQ0FBQyxjQUFjLEVBQUU7Z0JBQ3ZCLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUMzQjtTQUNKO1FBRUQsSUFBSSxvQkFBb0IsRUFBRTtZQUN0QixpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBRXBEO2FBQU07WUFDSCxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRTtnQkFDL0IsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsS0FBSyxFQUFFLFFBQVE7b0JBRW5ELElBQUksS0FBSyxFQUFFO3dCQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ3BCLFVBQVUsQ0FBQzs0QkFDUCxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO3dCQUNuRCxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7cUJBQ3JCO3lCQUFNO3dCQUNILGlCQUFpQixDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7cUJBQ3ZEO2dCQUNMLENBQUMsQ0FBQyxDQUFBO2FBQ0w7aUJBQU07Z0JBQ0gsaUJBQWlCLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNwRDtTQUNKO0lBQ0wsQ0FBQztJQUdELFNBQVMsaUJBQWlCLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxjQUFjO1FBQzdELE1BQU0sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFFcEQsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRVgsS0FBSyxHQUFHLGNBQWMsSUFBSSxLQUFLLENBQUM7UUFFaEMsSUFBSSxLQUFLLENBQUM7UUFDVixJQUFJLFNBQVMsRUFBRTtZQUNYLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM3QjthQUFNO1lBQ0gsS0FBSyxHQUFHLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2hDO1FBRUQsS0FBSyxDQUFDLE1BQU0sR0FBRztZQUNYLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEdBQUcsVUFBVSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1lBQ2pFLFlBQVksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0IsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUNyQixzQkFBc0IsRUFBRSxDQUFDO1lBQ3pCLElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxFQUFFO2dCQUN4QixNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDMUI7WUFFRCxLQUFLLENBQUMsT0FBTyxHQUFHLG1CQUFtQixDQUFDO1FBQ3hDLENBQUMsQ0FBQztRQUVGLElBQUksY0FBYyxHQUFHLFVBQVUsS0FBSztZQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRTNDLElBQUksVUFBVSxLQUFLLFVBQVUsRUFBRTtnQkFDM0IsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO29CQUNyQixNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7aUJBQ3pCO2FBQ0o7aUJBQU07Z0JBQ0gsVUFBVSxDQUFDO29CQUNQLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQzthQUNyQjtRQUNMLENBQUMsQ0FBQztRQUVGLEtBQUssQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDO1FBRS9CLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQUssR0FBRztRQUNULE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDZixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZixDQUFDLENBQUM7SUFJRixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsTUFBTTtRQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFFL0MsSUFBSSxNQUFNLEVBQUU7WUFDUixNQUFNLENBQUMsS0FBSyxDQUFDLDRCQUE0QixHQUFHLE1BQU0sR0FBRyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQ3hGLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN0QixLQUFLLEdBQUcsMkJBQTJCLENBQUM7WUFFcEMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1lBRTVCLFVBQVUsQ0FBQztnQkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLDhCQUE4QixHQUFHLFNBQVMsQ0FBQyxDQUFDO2dCQUN6RCxLQUFLLEdBQUcsU0FBUyxDQUFDO2dCQUVsQixvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFFakMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQ2Q7UUFFRCxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZixDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsV0FBVyxHQUFHO1FBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM1QixrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLE9BQU87UUFDekIsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQixDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsVUFBVSxJQUFJLEVBQUUsUUFBUTtRQUM1QyxzQkFBc0IsR0FBRztZQUNyQixFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQztRQUVGLHNCQUFzQixFQUFFLENBQUM7SUFDN0IsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELE1BQU0sQ0FBQyxPQUFPLEdBQUcseUJBQXlCLENBQUM7Ozs7O0FDL04zQyxJQUFJLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtBQUM5QixJQUFHLE1BQU0sQ0FBQyxjQUFjLEVBQ3hCO0lBQ0UsSUFDQTtRQUNFLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUNwQztJQUNELE9BQU0sQ0FBQyxFQUNQO1FBQ0Usa0JBQWtCLEdBQUcsSUFBSSxDQUFBO0tBQzFCO0NBQ0Y7QUFHRCxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUU7SUFDNUIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsVUFBUyxLQUFLO1FBQ3RDLElBQUksT0FBTyxJQUFJLEtBQUssVUFBVSxFQUFFO1lBRzlCLE1BQU0sSUFBSSxTQUFTLENBQUMsc0VBQXNFLENBQUMsQ0FBQztTQUM3RjtRQUVELElBQUksS0FBSyxHQUFLLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQ2xELE9BQU8sR0FBRyxJQUFJLEVBQ2QsSUFBSSxHQUFNLGNBQVksQ0FBQyxFQUN2QixNQUFNLEdBQUk7WUFDUixPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxZQUFZLElBQUksSUFBSSxLQUFLO2dCQUMzQyxDQUFDLENBQUMsSUFBSTtnQkFDTixDQUFDLENBQUMsS0FBSyxFQUNQLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUM7UUFFTixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDaEMsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBRTlCLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsQ0FBQztDQUNIO0FBR0QsSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFlBQVksQ0FBQztBQUVsRCxJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFbkMsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ25DLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUdqQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7QUFHeEIsU0FBUyxvQkFBb0IsQ0FBQyxlQUFlO0lBRTNDLElBQUcsQ0FBQyxlQUFlO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFFL0IsS0FBSSxJQUFJLEdBQUcsSUFBSSxlQUFlLEVBQzlCO1FBQ0UsSUFBSSxLQUFLLEdBQUcsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWpDLElBQUcsT0FBTyxLQUFLLElBQUksUUFBUTtZQUN6QixlQUFlLENBQUMsR0FBRyxDQUFDO2dCQUNwQjtvQkFDRSxRQUFRLEVBQUUsS0FBSztpQkFDaEIsQ0FBQTtLQUNKO0lBQUEsQ0FBQztJQUVGLE9BQU8sZUFBZSxDQUFDO0FBQ3pCLENBQUM7QUFBQSxDQUFDO0FBRUYsU0FBUyxjQUFjLENBQUMsU0FBUztJQUUvQixJQUFHLENBQUMsU0FBUztRQUFFLE9BQU87SUFHdEIsSUFBRyxTQUFTLFlBQVksUUFBUTtRQUM5QixPQUFPLEVBQUMsSUFBSSxFQUFFLFNBQVMsRUFBQyxDQUFDO0lBRzNCLElBQUcsU0FBUyxDQUFDLElBQUksWUFBWSxRQUFRO1FBQ25DLE9BQU8sU0FBUyxDQUFDO0lBR25CLElBQUcsU0FBUyxDQUFDLFdBQVcsWUFBWSxRQUFRLEVBQzVDO1FBQ0UsU0FBUyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDO1FBQ3ZDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0lBR0QsSUFBRyxTQUFTLENBQUMsS0FBSyxZQUFZLFFBQVEsRUFDdEM7UUFDRSxTQUFTLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDakMsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFHRCxJQUFHLFNBQVMsQ0FBQyxTQUFTLEtBQUssU0FBUztRQUFFLE9BQU87SUFDN0MsSUFBRyxTQUFTLENBQUMsS0FBSyxZQUFZLFFBQVE7UUFBRSxPQUFPO0lBRS9DLE1BQU0sSUFBSSxXQUFXLENBQUMsZ0RBQWdELENBQUMsQ0FBQztBQUMxRSxDQUFDO0FBQUEsQ0FBQztBQWFGLFNBQVMsZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNO0lBRXJDLElBQUcsa0JBQWtCLEVBQ3JCO1FBQ0UsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7S0FDckI7U0FFRDtRQUNFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7UUFDekUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztLQUMxRTtBQUNILENBQUM7QUFBQSxDQUFDO0FBZ0JGLFNBQVMsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFFdkQsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBRWhCLElBQUcsQ0FBQyxNQUFNO1FBQ1IsTUFBTSxJQUFJLFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBRWpELElBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07UUFDL0IsTUFBTSxJQUFJLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBRTdDLElBQUksZUFBZSxHQUFHLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUduRSxJQUFHLE9BQU8sWUFBWSxRQUFRLEVBQzlCO1FBQ0UsSUFBRyxTQUFTLElBQUksU0FBUztZQUN2QixNQUFNLElBQUksV0FBVyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFFckUsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNwQixTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3RCLE9BQU8sR0FBSyxTQUFTLENBQUM7S0FDdkI7SUFBQSxDQUFDO0lBRUYsSUFBRyxPQUFPLElBQUksT0FBTyxDQUFDLElBQUksWUFBWSxRQUFRLEVBQzlDO1FBQ0UsSUFBRyxTQUFTLElBQUksQ0FBQyxDQUFDLFNBQVMsWUFBWSxRQUFRLENBQUM7WUFDOUMsTUFBTSxJQUFJLFdBQVcsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBRWxFLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDdEIsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNwQixPQUFPLEdBQUssU0FBUyxDQUFDO0tBQ3ZCO0lBQUEsQ0FBQztJQUVGLElBQUcsU0FBUyxZQUFZLFFBQVEsRUFDaEM7UUFDRSxJQUFHLFNBQVMsSUFBSSxTQUFTO1lBQ3ZCLE1BQU0sSUFBSSxXQUFXLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUVyRSxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3RCLFNBQVMsR0FBRyxTQUFTLENBQUM7S0FDdkI7SUFBQSxDQUFDO0lBRUYsSUFBRyxTQUFTLElBQUksU0FBUyxDQUFDLElBQUksWUFBWSxRQUFRO1FBQ2hELElBQUcsU0FBUyxJQUFJLENBQUMsQ0FBQyxTQUFTLFlBQVksUUFBUSxDQUFDO1lBQzlDLE1BQU0sSUFBSSxXQUFXLENBQUMsd0NBQXdDLENBQUMsQ0FBQztJQUVwRSxPQUFPLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUd4QixZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXhCLElBQUcsU0FBUztRQUNWLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBR2hDLElBQUcsa0JBQWtCO1FBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQTs7UUFFNUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDO0lBRWpFLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDO0lBRzNDLFNBQVMsZ0JBQWdCLENBQUMsS0FBSztRQUU3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUFBLENBQUM7SUFFRixJQUFJLENBQUMsWUFBWSxHQUFHO1FBRWxCLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUMsQ0FBQTtJQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsVUFBUyxLQUFLO1FBR2hDLElBQUcsU0FBUyxFQUNaO1lBRUUsSUFBRyxTQUFTLENBQUMsbUJBQW1CO2dCQUM5QixTQUFTLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7aUJBR3hELElBQUcsU0FBUyxDQUFDLGNBQWM7Z0JBQzlCLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7U0FDdEQ7UUFBQSxDQUFDO1FBR0YsSUFBRyxLQUFLLEVBQ1I7WUFFRSxJQUFHLEtBQUssQ0FBQyxnQkFBZ0I7Z0JBQ3ZCLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztpQkFHakQsSUFBRyxLQUFLLENBQUMsV0FBVztnQkFDdkIsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztTQUMvQztRQUFBLENBQUM7UUFFRixTQUFTLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUMsQ0FBQTtJQUVELElBQUcsQ0FBQyxrQkFBa0I7UUFDcEIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUN2QztZQUNFLEdBQUcsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDakMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNsQyxDQUFDLENBQUE7SUFFSixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRzdCLElBQUksZUFBZSxHQUFRLE9BQU8sQ0FBQyxlQUFlLElBQVMsWUFBWSxDQUFDO0lBQ3hFLElBQUksb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixJQUFJLGVBQWUsQ0FBQztJQUMzRSxJQUFJLGdCQUFnQixHQUFPLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBUSxZQUFZLENBQUM7SUFDeEUsSUFBSSxrQkFBa0IsR0FBSyxPQUFPLENBQUMsa0JBQWtCLElBQU0sWUFBWSxDQUFDO0lBR3hFLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztJQUVsQixJQUFJLFFBQVEsR0FBSSxJQUFJLE1BQU0sRUFBRSxDQUFDO0lBQzdCLElBQUksU0FBUyxHQUFHLElBQUksTUFBTSxFQUFFLENBQUM7SUFDN0IsSUFBSSxrQkFBa0IsR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDO0lBRXRDLElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztJQU1yQixTQUFTLGFBQWEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUk7UUFFdEMsSUFBSSxRQUFRLEdBQ1o7WUFDRSxPQUFPLEVBQUUsT0FBTztZQUVoQixPQUFPLEVBQUUsVUFBVSxDQUFDO2dCQUVsQixTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM3QixDQUFDLEVBQ0QsZ0JBQWdCLENBQUM7U0FDbEIsQ0FBQztRQUVGLFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBQUEsQ0FBQztJQUtGLFNBQVMsc0JBQXNCLENBQUMsR0FBRyxFQUFFLElBQUk7UUFFdkMsSUFBSSxPQUFPLEdBQUcsVUFBVSxDQUFDO1lBRXZCLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxFQUNELGtCQUFrQixDQUFDLENBQUM7UUFFcEIsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUFBLENBQUM7SUFnQkYsU0FBUyxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVM7UUFFckQsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTNDLElBQUksQ0FBQyxZQUFZLEdBQUc7WUFFbEIsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQyxDQUFBO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxVQUFTLEtBQUs7WUFFaEMsU0FBUyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUE7UUFFRCxJQUFHLENBQUMsa0JBQWtCO1lBQ3BCLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFDdkM7Z0JBQ0UsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDakMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzthQUNsQyxDQUFDLENBQUE7UUFFSixJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUt2QyxJQUFHLENBQUMsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLEVBQ3RDO1lBQ0UsSUFBRyxrQkFBa0I7Z0JBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBOztnQkFFbkMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUN4QztvQkFDRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQztpQkFDekIsQ0FBQyxDQUFDO1NBQ047UUFFRCxJQUFJLGNBQWMsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFN0MsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBVTlDLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBUyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVM7WUFHNUMsSUFBRyxLQUFLLFlBQVksUUFBUSxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsSUFBSSxZQUFZLFFBQVEsRUFDdkU7Z0JBQ0UsSUFBRyxNQUFNLElBQUksU0FBUztvQkFDcEIsTUFBTSxJQUFJLFdBQVcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO2dCQUVwRSxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUNsQixNQUFNLEdBQUcsSUFBSSxDQUFDO2dCQUNkLEtBQUssR0FBRyxTQUFTLENBQUM7YUFDbkI7aUJBRUksSUFBRyxNQUFNLFlBQVksUUFBUTttQkFDL0IsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLFlBQVksUUFBUSxFQUM1QztnQkFDRSxJQUFHLFNBQVMsSUFBSSxTQUFTO29CQUN2QixNQUFNLElBQUksV0FBVyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7Z0JBRXBFLFNBQVMsR0FBRyxNQUFNLENBQUM7Z0JBQ25CLE1BQU0sR0FBRyxJQUFJLENBQUM7YUFDZjtZQUFBLENBQUM7WUFFRixTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBR3RDLElBQUcsUUFBUTtnQkFDVCxZQUFZLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRWpDLElBQUcsSUFBSSxJQUFJLFNBQVMsRUFDcEI7Z0JBQ0UsSUFBRyxLQUFLO29CQUNOLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUVwQixJQUFHLE1BQU07b0JBQ1AsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7YUFDdEI7WUFBQSxDQUFDO1lBRUYsSUFBSSxPQUFPLENBQUM7WUFHWixJQUFHLEtBQUssSUFBSSxNQUFNLElBQUksU0FBUyxFQUMvQjtnQkFDRSxJQUFHLElBQUksQ0FBQyxNQUFNLElBQUksU0FBUyxFQUMzQjtvQkFDRSxJQUFHLEtBQUs7d0JBQ04sS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDOzt3QkFFekIsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO2lCQUM3QjtnQkFHRCxJQUFHLGNBQWMsRUFDakI7b0JBQ0UsSUFBRyxjQUFjLENBQUMsS0FBSyxJQUFJLFNBQVMsSUFBSSxLQUFLO3dCQUMzQyxPQUFPOzRCQUNQO2dDQUNFLEtBQUssRUFBRSxLQUFLOzZCQUNiLENBQUM7eUJBR0o7d0JBQ0UsSUFBSSxNQUFNLEdBQUcsS0FBSzs0QkFDUCxDQUFDLENBQUMsY0FBYyxDQUFDLEtBQUs7NEJBQ3RCLENBQUMsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDO3dCQUVyQyxPQUFPOzRCQUNQO2dDQUNFLE1BQU0sRUFBRSxNQUFNO2dDQUNkLE1BQU0sRUFBRSxLQUFLLElBQUksTUFBTTs2QkFDeEIsQ0FBQztxQkFDSDtpQkFDRjs7b0JBRUMsT0FBTzt3QkFDUDs0QkFDRSxLQUFLLEVBQUcsS0FBSzs0QkFDYixNQUFNLEVBQUUsTUFBTTt5QkFDZixDQUFDO2dCQUVKLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQzthQUNwQztpQkFHSSxJQUFHLFFBQVE7Z0JBQ2QsT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7O2dCQUkzQixPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUc1QyxhQUFhLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUdqQyxTQUFTLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFcEUsSUFBRyxTQUFTO2dCQUNWLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVqQyxPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDLENBQUE7SUFDSCxDQUFDO0lBQUEsQ0FBQztJQUNGLFFBQVEsQ0FBQyxVQUFVLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFHdEMsU0FBUyxNQUFNLENBQUMsT0FBTztRQUVyQixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0IsSUFBRyxDQUFDLEdBQUc7WUFBRSxPQUFPO1FBRWhCLE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTVCLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MsSUFBRyxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXBCLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFHOUIsc0JBQXNCLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUFBLENBQUM7SUFPRixJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVMsT0FBTztRQUU1QixJQUFHLE9BQU87WUFBRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVuQyxLQUFJLElBQUksT0FBTyxJQUFJLFdBQVc7WUFDNUIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BCLENBQUMsQ0FBQztJQUdGLElBQUksQ0FBQyxLQUFLLEdBQUc7UUFHWCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEMsSUFBRyxTQUFTLElBQUksU0FBUyxDQUFDLEtBQUs7WUFDN0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUcxQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFZCxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFHekMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxVQUFTLFFBQVE7WUFFakMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQWVGLElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBUyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsUUFBUTtRQUc5RCxJQUFHLE1BQU0sWUFBWSxRQUFRLEVBQzdCO1lBQ0UsSUFBRyxJQUFJLElBQUksU0FBUztnQkFDbEIsTUFBTSxJQUFJLFdBQVcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1lBRXBFLFFBQVEsR0FBSSxNQUFNLENBQUM7WUFDbkIsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUN0QixJQUFJLEdBQVEsU0FBUyxDQUFDO1lBQ3RCLE1BQU0sR0FBTSxTQUFTLENBQUM7U0FDdkI7YUFFSSxJQUFHLElBQUksWUFBWSxRQUFRLEVBQ2hDO1lBQ0UsSUFBRyxTQUFTLElBQUksU0FBUztnQkFDdkIsTUFBTSxJQUFJLFdBQVcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1lBRXBFLFFBQVEsR0FBSSxJQUFJLENBQUM7WUFDakIsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUN0QixJQUFJLEdBQVEsU0FBUyxDQUFDO1NBQ3ZCO2FBRUksSUFBRyxTQUFTLFlBQVksUUFBUSxFQUNyQztZQUNFLElBQUcsUUFBUSxJQUFJLFNBQVM7Z0JBQ3RCLE1BQU0sSUFBSSxXQUFXLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUVwRSxRQUFRLEdBQUksU0FBUyxDQUFDO1lBQ3RCLFNBQVMsR0FBRyxTQUFTLENBQUM7U0FDdkI7UUFBQSxDQUFDO1FBRUYsSUFBRyxJQUFJLENBQUMsTUFBTSxJQUFJLFNBQVMsRUFDM0I7WUFDRSxNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQztZQUV0QixNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7U0FDM0I7UUFBQSxDQUFDO1FBRUYsSUFBRyxJQUFJLElBQUksU0FBUyxFQUNwQjtZQUNFLE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO1lBRXRCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1NBQ3BCO1FBQUEsQ0FBQztRQUdGLElBQUksT0FBTyxHQUNYO1lBQ0UsTUFBTSxFQUFFLE1BQU07WUFDZCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUM7UUFFRixJQUFHLFFBQVEsRUFDWDtZQUNFLElBQUksRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1lBQ3JCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztZQUVoQixPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFbkMsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsTUFBTTtnQkFFckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFckIsUUFBUSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxQixDQUFDO1lBQUEsQ0FBQztZQUVGLElBQUksT0FBTyxHQUNYO2dCQUNFLE9BQU8sRUFBVSxPQUFPO2dCQUN4QixRQUFRLEVBQVMsZ0JBQWdCO2dCQUNqQyxlQUFlLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7YUFDL0MsQ0FBQztZQUVGLElBQUksZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRWpELFNBQVMsV0FBVyxDQUFDLFNBQVM7Z0JBRTVCLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUN0RSxPQUFPLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDakUsV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFDLENBQUM7Z0JBQzVDLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFaEMsU0FBUyxHQUFHLFNBQVMsSUFBSSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ2pFLElBQUcsU0FBUztvQkFDVixPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRWpDLE9BQU8sT0FBTyxDQUFDO1lBQ2pCLENBQUM7WUFBQSxDQUFDO1lBRUYsU0FBUyxLQUFLLENBQUMsU0FBUztnQkFFdEIsU0FBUyxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUMsNkJBQTZCLEVBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRTVELElBQUksT0FBTyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQy9DLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFdEIsT0FBTyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEMsQ0FBQztZQUFBLENBQUM7WUFFRixTQUFTLE9BQU87Z0JBRWQsSUFBRyxPQUFPLEdBQUcsV0FBVztvQkFDdEIsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBRTFCLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7Z0JBQzNDLEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO2dCQUU1QixLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztnQkFFcEIsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDekIsQ0FBQztZQUFBLENBQUM7WUFFRixPQUFPLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUMvQjtRQUFBLENBQUM7UUFHRixPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUvQixTQUFTLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM3QyxJQUFHLFNBQVM7WUFDVixPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFakMsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQyxDQUFDO0lBYUYsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFTLE9BQU8sRUFBRSxTQUFTO1FBRXZDLElBQUcsQ0FBQyxPQUFPO1lBQ1QsTUFBTSxJQUFJLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBRWhELElBQ0E7WUFDRSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNsQztRQUNELE9BQU0sQ0FBQyxFQUNQO1lBRUUsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNsQztRQUFBLENBQUM7UUFFRixJQUFJLEVBQUUsR0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3hCLElBQUksR0FBRyxHQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDekIsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUM1QixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUVsQyxJQUFJLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ3ZCLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFHdkIsSUFBRyxJQUFJLENBQUMsTUFBTSxJQUFJLFNBQVMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBRzNELElBQUcsRUFBRSxJQUFJLFNBQVMsSUFBSSxHQUFHLElBQUksU0FBUyxFQUN0QztZQUNFLElBQUksWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUV2RCxJQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQztnQkFBRSxPQUFPO1lBQzlDLE9BQU8sWUFBWSxDQUFDO1NBQ3JCO1FBQUEsQ0FBQztRQUdGLFNBQVMsY0FBYztZQUdyQixTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUM3RCxJQUFHLFNBQVMsRUFDWjtnQkFDRSxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDdkMsSUFBRyxRQUFRO29CQUNULE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDM0M7WUFBQSxDQUFDO1lBRUYsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3pDLElBQUksT0FBTyxHQUFHLElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVyRSxJQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztnQkFBRSxPQUFPO1lBQ3pDLE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7UUFBQSxDQUFDO1FBRUYsU0FBUyxlQUFlLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNO1lBRTdDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFBQSxDQUFDO1FBRUYsU0FBUyxrQkFBa0IsQ0FBQyxPQUFPO1lBRWpDLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFHcEQsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLHNCQUFzQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBQUEsQ0FBQztRQUlGLElBQUcsTUFBTSxFQUNUO1lBRUUsSUFBRyxJQUFJLElBQUksU0FBUyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxFQUMzQztnQkFDRSxJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDdEMsSUFBRyxPQUFPLEVBQ1Y7b0JBQ0UsSUFBSSxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztvQkFFOUMsSUFBRyxNQUFNLElBQUksZUFBZSxDQUFDLEtBQUs7d0JBQ2hDLE9BQU8sZUFBZSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztvQkFFMUMsSUFBRyxNQUFNLElBQUksZUFBZSxDQUFDLFFBQVE7d0JBQ25DLE9BQU8sZUFBZSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBRWhELE9BQU8sY0FBYyxFQUFFLENBQUM7aUJBQ3pCO2dCQUVELElBQUksU0FBUyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2xELElBQUcsU0FBUztvQkFDVixPQUFPLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ3hDO1lBR0QsT0FBTyxjQUFjLEVBQUUsQ0FBQztTQUN6QjtRQUFBLENBQUM7UUFFRixJQUFJLEtBQUssR0FBSSxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQzNCLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFHNUIsSUFBRyxLQUFLLElBQUssS0FBSyxDQUFDLElBQUksSUFBSyxLQUFLLENBQUMsSUFBSSxJQUFLLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUMvRCxJQUFHLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBRy9ELElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RDLElBQUcsQ0FBQyxPQUFPLEVBQ1g7WUFDRSxJQUFJLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xELElBQUcsU0FBUztnQkFDVixPQUFPLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXZDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUMxRTtRQUFBLENBQUM7UUFHRixlQUFlLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBQUEsQ0FBQztBQUNGLFFBQVEsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFHbkMsVUFBVSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7QUFHN0MsTUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUM7QUFFNUIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ25DLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBRWpELFVBQVUsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0FBQzdCLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztBQUMzQyxVQUFVLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQzs7O0FDenlCN0IsU0FBUyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUU7SUFFdkIsSUFBSSxNQUFNLEdBQ1Y7UUFDRSxPQUFPLEVBQUUsS0FBSztLQUNmLENBQUM7SUFHRixJQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQ2pCO1FBQ0UsTUFBTSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBRS9CLElBQUcsT0FBTyxDQUFDLE1BQU07WUFDZixNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFHakMsSUFBRyxFQUFFLElBQUksU0FBUztZQUNoQixNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUNsQjtTQUdJLElBQUcsRUFBRSxJQUFJLFNBQVMsRUFDdkI7UUFDRSxJQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQ2hCO1lBQ0UsSUFBRyxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVM7Z0JBQzdCLE1BQU0sSUFBSSxTQUFTLENBQUMsbUNBQW1DLENBQUMsQ0FBQztZQUUzRCxNQUFNLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDOUI7YUFDSSxJQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUztZQUNsQyxNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7O1lBRS9CLE1BQU0sSUFBSSxTQUFTLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUV2RCxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUNoQjtJQUFBLENBQUM7SUFFRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUFBLENBQUM7QUFXRixTQUFTLE1BQU0sQ0FBQyxPQUFPO0lBRXJCLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQztJQUVyQixJQUFHLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLFlBQVksTUFBTSxFQUFFO1FBQzNELE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQzlCO0lBSUQsSUFBSSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUM3QixJQUFHLE9BQU8sS0FBSyxLQUFLO1FBQ2xCLE1BQU0sSUFBSSxTQUFTLENBQUMsMkJBQTJCLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQztJQUcvRSxJQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksU0FBUyxFQUM3QjtRQUNFLElBQUcsTUFBTSxDQUFDLEVBQUUsSUFBSSxTQUFTO1lBQ3ZCLE1BQU0sSUFBSSxTQUFTLENBQUMsbUJBQW1CLEdBQUMsT0FBTyxDQUFDLENBQUM7UUFFbkQsSUFBSSxjQUFjLEdBQUcsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUM7UUFDakQsSUFBSSxhQUFhLEdBQUksTUFBTSxDQUFDLEtBQUssS0FBTSxTQUFTLENBQUM7UUFHakQsSUFBRyxjQUFjLElBQUksYUFBYTtZQUNoQyxNQUFNLElBQUksU0FBUyxDQUFDLHFDQUFxQyxHQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXJFLElBQUcsQ0FBQyxjQUFjLElBQUksQ0FBQyxhQUFhO1lBQ2xDLE1BQU0sSUFBSSxTQUFTLENBQUMsaUNBQWlDLEdBQUMsT0FBTyxDQUFDLENBQUM7UUFFakUsTUFBTSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQztLQUNsQjtJQUdELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFBQSxDQUFDO0FBR0YsT0FBTyxDQUFDLElBQUksR0FBSyxJQUFJLENBQUM7QUFDdEIsT0FBTyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7OztBQ3RHeEIsU0FBUyxJQUFJLENBQUMsT0FBTztJQUVuQixNQUFNLElBQUksU0FBUyxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUFBLENBQUM7QUFFRixTQUFTLE1BQU0sQ0FBQyxPQUFPO0lBRXJCLE1BQU0sSUFBSSxTQUFTLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBQUEsQ0FBQztBQUdGLE9BQU8sQ0FBQyxJQUFJLEdBQUssSUFBSSxDQUFDO0FBQ3RCLE9BQU8sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOzs7QUNaeEIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ25DLElBQUksTUFBTSxHQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUdsQyxPQUFPLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUMxQixPQUFPLENBQUMsTUFBTSxHQUFJLE1BQU0sQ0FBQzs7O0FDb0J6QixNQUFNLENBQUMsV0FBVyxHQUFHLFVBQVUsYUFBYSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0I7SUFDcEUsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRTtRQUV4RyxRQUFRLENBQUM7WUFDTCxLQUFLLEVBQUUsSUFBSTtTQUNkLENBQUMsQ0FBQztRQUNILE9BQU87S0FDVjtJQUtELElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUU7UUFDN0IsUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDdEIsS0FBSyxFQUFFO2dCQUNILGNBQWMsRUFBRSxhQUFhO2dCQUM3QixXQUFXLEVBQUUsYUFBYTthQUM3QjtTQUNKLENBQUMsQ0FBQztRQUNILE9BQU87S0FDVjtJQUVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUVyRCxTQUFTLGdCQUFnQixDQUFDLEtBQUs7UUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUV4QixJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDaEMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixLQUFLLHVCQUF1QixFQUFFO2dCQUM1RCxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQzthQUNqQztpQkFBTTtnQkFDSCxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsb0JBQW9CLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7YUFDL0k7WUFHRCxNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7U0FDM0Q7UUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDbEMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDO1lBR3pHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztTQUMzRDtJQUNMLENBQUM7SUFFRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7UUFDbkIsVUFBVSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQzNDO1NBQ0k7UUFDRCxVQUFVLENBQUM7WUFDUCxzQkFBc0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNYO0FBQ0wsQ0FBQyxDQUFDO0FBRUYsU0FBUyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLG9CQUFvQjtJQUMvRCxJQUFJLGtCQUFrQixHQUFHO1FBQ3JCLEtBQUssRUFBRSxLQUFLO1FBQ1osS0FBSyxFQUFFO1lBQ0gsU0FBUyxFQUFFO2dCQUNQLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUMvQyxRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDakUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUk7YUFDdkU7WUFDRCxRQUFRLEVBQUUsRUFBRTtTQUNmO0tBQ0osQ0FBQztJQUVGLElBQUksQ0FBQyxDQUFDLG9CQUFvQixFQUFFO1FBQ3hCLGtCQUFrQixDQUFDLEtBQUssR0FBRztZQUN2QixTQUFTLEVBQUU7Z0JBQ1AsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFFbEQ7WUFDRCxRQUFRLEVBQUUsRUFBRTtTQUNmLENBQUM7S0FDTDtJQUVELElBQUksUUFBUSxFQUFFO1FBQ1Ysa0JBQWtCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsR0FBRyxRQUFRLENBQUM7UUFFbEUsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLElBQUksa0JBQWtCLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtZQUNoRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztTQUNyRTtLQUNKO0lBRUQsT0FBTyxrQkFBa0IsQ0FBQztBQUM5QixDQUFDO0FBRUQsU0FBUyxzQkFBc0IsQ0FBQyxnQkFBZ0I7SUFDNUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUNULFVBQVUsQ0FBQztZQUNQLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPO0tBQ1Y7SUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUNsQixVQUFVLENBQUM7WUFDUCxzQkFBc0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNSLE9BQU87S0FDVjtJQUVELElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtRQUNuQixNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQztZQUM3QixlQUFlLEVBQUUsSUFBSTtTQUN4QixFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ1g7U0FDSSxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUU7UUFDakMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7WUFDN0IscUJBQXFCLEVBQUUsZ0JBQWdCO1NBQzFDLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDWDtTQUNJO1FBQ0QsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7WUFDN0Isd0JBQXdCLEVBQUUsSUFBSTtTQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ1g7QUFDTCxDQUFDO0FBRUQsSUFBSSxNQUFNLENBQUM7QUFHWCxNQUFNLENBQUMsb0JBQW9CLEdBQUcsVUFBVSxRQUFRO0lBQzVDLFVBQVUsQ0FBQztRQUNQLFdBQVcsQ0FBQyxVQUFVLEtBQUssRUFBRSxRQUFRLEVBQUUsa0JBQWtCO1lBQ3JELElBQUksQ0FBQyxrQkFBa0IsRUFBRTtnQkFDckIsa0JBQWtCLEdBQUc7b0JBQ2pCLEtBQUssRUFBRSxJQUFJO2lCQUNkLENBQUM7YUFDTDtZQUVELFFBQVEsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQztBQUVGLFNBQVMsVUFBVSxDQUFDLFlBQVk7SUFDNUIsSUFBSSxNQUFNLEVBQUU7UUFDUixZQUFZLEVBQUUsQ0FBQztRQUNmLE9BQU87S0FDVjtJQUVELE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sQ0FBQyxNQUFNLEdBQUc7UUFDWixNQUFNLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUN2QixZQUFZLEVBQUUsQ0FBQztJQUNuQixDQUFDLENBQUM7SUFDRixNQUFNLENBQUMsR0FBRyxHQUFHLHNFQUFzRSxDQUFDO0lBQ3BGLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztJQUM5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQsTUFBTSxDQUFDLHdCQUF3QixHQUFHLFVBQVUsUUFBUTtJQUVoRCxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFO1FBQzdCLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzlCLE9BQU87S0FDVjtJQUVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUVyRCxTQUFTLGdCQUFnQixDQUFDLEtBQUs7UUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUV4QixJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDbEMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUczQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7U0FDM0Q7SUFDTCxDQUFDO0lBRUQsVUFBVSxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3pELENBQUMsQ0FBQztBQUVGLFNBQVMsbUNBQW1DO0lBQ3hDLElBQUksQ0FBQyxNQUFNLEVBQUU7UUFDVCxVQUFVLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUNoRCxPQUFPO0tBQ1Y7SUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUNsQixVQUFVLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDckQsT0FBTztLQUNWO0lBRUQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7UUFDN0Isd0JBQXdCLEVBQUUsSUFBSTtLQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ1osQ0FBQztBQUVELE9BQU8sQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDOzs7QUMxTmxDLElBQUksaUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBQ2pDLElBQUksUUFBUSxDQUFDO0FBQ2IsSUFBSSxjQUFjLENBQUM7QUFDbkIsSUFBSSxTQUFTLEdBQUcsT0FBTyxNQUFNLENBQUMsY0FBYyxLQUFLLFdBQVcsQ0FBQztBQUM3RCxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUUsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUM7QUFFM0MsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxVQUFVLEtBQUs7SUFDOUMsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1FBQ3hDLE9BQU87S0FDVjtJQUNELGlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNsQyxDQUFDLENBQUMsQ0FBQztBQUdILFNBQVMsaUJBQWlCLENBQUMsSUFBSTtJQUUzQixJQUFJLElBQUksSUFBSSx1QkFBdUIsRUFBRTtRQUNqQyxJQUFJLGNBQWM7WUFDZCxPQUFPLGNBQWMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDOztZQUUvQyxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7S0FDaEQ7SUFFRCxJQUFJLElBQUksSUFBSSxxQ0FBcUMsRUFBRTtRQUMvQyxpQkFBaUIsR0FBRyxTQUFTLENBQUM7S0FDakM7SUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksY0FBYyxFQUFFO1FBQ2pDLGNBQWMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEtBQUssSUFBSSxDQUFDLENBQUM7S0FDaEY7QUFDTCxDQUFDO0FBR0QsU0FBUywwQkFBMEIsQ0FBQyxRQUFRO0lBQ3hDLElBQUksQ0FBQyxRQUFRO1FBQUUsT0FBTztJQUN0QixJQUFJLGlCQUFpQixJQUFJLFNBQVM7UUFBRSxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUcxRCxNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN6QyxVQUFVLENBQUM7UUFDUCxJQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRTtZQUMvQixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbkI7O1lBQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNiLENBQUM7QUFHRCxTQUFTLFdBQVcsQ0FBQyxRQUFRO0lBQ3pCLElBQUksQ0FBQyxRQUFRO1FBQ1QsTUFBTSxvQ0FBb0MsQ0FBQztJQUMvQyxJQUFJLFFBQVE7UUFDUixPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QixjQUFjLEdBQUcsUUFBUSxDQUFDO0lBQzFCLE1BQU0sQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFHRCxTQUFTLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxRQUFRO0lBQ3BDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTztRQUFFLE1BQU0sdURBQXVELENBQUM7SUFDeEYsSUFBSSxDQUFDLFFBQVE7UUFBRSxNQUFNLG9DQUFvQyxDQUFDO0lBRTFELElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXhDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDMUIsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUNmLHFCQUFxQixFQUFFLEdBQUc7S0FDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNaLENBQUM7QUFHRCxTQUFTLG9CQUFvQixDQUFDLFFBQVE7SUFDbEMsSUFBSSxDQUFDLFFBQVE7UUFBRSxNQUFNLG9DQUFvQyxDQUFDO0lBQzFELElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXhDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDMUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsUUFBUTtJQUNuRCxJQUFJLFNBQVM7UUFDVCxPQUFPLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNsQyxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO1FBQ3ZCLFFBQVEsR0FBRyxXQUFXLENBQUM7UUFDdkIsV0FBVyxHQUFHLGtDQUFrQyxDQUFDO0tBQ3BEO0lBQ0QsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxLQUFLLENBQUMsR0FBRyxHQUFHLHFCQUFxQixHQUFHLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDOUQsS0FBSyxDQUFDLE1BQU0sR0FBRztRQUNYLGlCQUFpQixHQUFHLFFBQVEsQ0FBQztRQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN6QyxVQUFVLENBQUM7WUFDUCxJQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRTtnQkFDL0IsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUM7YUFDbEM7O2dCQUNHLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUMsQ0FBQztJQUNGLEtBQUssQ0FBQyxPQUFPLEdBQUc7UUFDWixRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUIsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELFNBQVMsNkJBQTZCLENBQUMsUUFBUTtJQUMzQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUdELFNBQVMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLHdCQUF3QjtJQUM1RCxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2QsSUFBSSx3QkFBd0IsR0FBRztRQUMzQixjQUFjLEVBQUUsUUFBUTtRQUN4QixXQUFXLEVBQUUsUUFBUTtLQUN4QixDQUFDO0lBQ0YsSUFBSSxTQUFTO1FBQ1QsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLENBQUM7SUFHcEQsSUFBSSxrQkFBa0IsR0FBRztRQUNyQixTQUFTLEVBQUU7WUFDUCxpQkFBaUIsRUFBRSxpQkFBaUI7WUFDcEMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ25ELFNBQVMsRUFBRSxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSTtTQUN6RDtRQUNELFFBQVEsRUFBRSxFQUFFO0tBQ2YsQ0FBQztJQUlGLElBQUksaUJBQWlCLElBQUksU0FBUyxJQUFJLENBQUMsUUFBUSxFQUFFO1FBQzdDLElBQUksd0JBQXdCLEVBQUU7WUFDMUIsb0JBQW9CLENBQUMsVUFBVSxRQUFRLEVBQUUsb0JBQW9CO2dCQUN6RCxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUFDO2dCQUU1RCxJQUFJLG9CQUFvQixFQUFFO29CQUN0QixrQkFBa0IsQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7aUJBQ2xEO2dCQUNELFFBQVEsQ0FBQyxRQUFRLElBQUksdUJBQXVCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDeEYsQ0FBQyxDQUFDLENBQUM7U0FDTjthQUNJO1lBQ0QsV0FBVyxDQUFDLFVBQVUsUUFBUTtnQkFDMUIsa0JBQWtCLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztnQkFDNUQsUUFBUSxDQUFDLFFBQVEsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUN4RixDQUFDLENBQUMsQ0FBQztTQUNOO1FBQ0QsT0FBTztLQUNWO0lBR0QsSUFBSSxpQkFBaUIsSUFBSSxTQUFTLEVBQUU7UUFDaEMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztLQUMvRDtJQUdELFFBQVEsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBRUQsT0FBTyxDQUFDLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO0FBQ3BELE9BQU8sQ0FBQyw2QkFBNkIsR0FBRyw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLENBQUMsMEJBQTBCLEdBQUcsMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxDQUFDLHdCQUF3QixHQUFHLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsSmxDLGlDQUFvQztBQUNwQywyQkFBOEI7QUFDOUIsbUNBQXNDO0FBZXRDO0lBV0ksb0JBQW9CLGFBQXNDO1FBQTFELGlCQTRCQztRQTVCbUIsa0JBQWEsR0FBYixhQUFhLENBQXlCO1FBUDFELDBCQUFxQixHQUFzQixFQUFFLENBQUM7UUFDOUMseUJBQW9CLEdBQXNCLEVBQUUsQ0FBQztRQUU3QyxxQkFBZ0IsR0FBc0IsRUFBRSxDQUFDO1FBRWpDLDJCQUFzQixHQUFHLEtBQUssQ0FBQztRQUduQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUUxSixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksaUJBQWlCLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUU1RCxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsR0FBRyxVQUFBLEtBQUs7WUFDMUIsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDbkIsSUFBTSxTQUFTLEdBQW9CLEtBQUssQ0FBQyxTQUFTLENBQUM7Z0JBQ25ELElBQUksU0FBUyxFQUFFO29CQUNYLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQWtCLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO29CQUNwRixLQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO29CQUNwQyxLQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7aUJBQ3REO3FCQUFNLElBQUksQ0FBQyxLQUFJLENBQUMsc0JBQXNCLEVBQUU7b0JBQ3JDLEtBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7aUJBQ3RDO2FBQ0o7UUFDTCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsRUFBRSxDQUFDLHNCQUFzQixHQUFHO1lBQzdCLElBQUksS0FBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLEtBQUssUUFBUSxFQUFFO2dCQUNyQyxPQUFPLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUNyQyxLQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBa0IsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7aUJBQzNFO2FBQ0o7UUFDTCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQVNELDBCQUFLLEdBQUw7UUFBQSxpQkFrQkM7UUFqQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLEtBQUssUUFBUSxFQUFFO2dCQUNyQyxNQUFNLENBQUMsa0pBQWtKLENBQUMsQ0FBQzthQUM5SjtZQUNELElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFO2dCQUNsQyxJQUFJLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRTtvQkFFeEIsSUFBTSxHQUFHLEdBQVEsS0FBSSxDQUFDLEVBQUUsQ0FBQztvQkFDekIsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2lCQUNqRDtxQkFBTTtvQkFDSCxLQUFvQixVQUEwQyxFQUExQyxLQUFBLEtBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxFQUExQyxjQUEwQyxFQUExQyxJQUEwQyxFQUFFO3dCQUEzRCxJQUFNLEtBQUssU0FBQTt3QkFDWixLQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztxQkFDM0Q7aUJBQ0o7Z0JBQ0QsT0FBTyxFQUFFLENBQUM7YUFDYjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELDRCQUFPLEdBQVAsVUFBUSw2QkFBc0M7UUFDMUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3RDLElBQUk7WUFDQSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7Z0JBQ1QsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsS0FBSyxRQUFRLEVBQUU7b0JBQ3JDLE9BQU87aUJBQ1Y7Z0JBQ0QsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztnQkFFL0IsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUU7b0JBR3hCLElBQU0sR0FBRyxHQUFRLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3pCLEtBQXFCLFVBQXFCLEVBQXJCLEtBQUEsR0FBRyxDQUFDLGVBQWUsRUFBRSxFQUFyQixjQUFxQixFQUFyQixJQUFxQixFQUFFO3dCQUF2QyxJQUFNLE1BQU0sU0FBQTt3QkFDYixJQUFJLENBQUMsNkJBQTZCLEVBQUU7NEJBQ2hDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQzt5QkFDakI7d0JBQ0QsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztxQkFDNUI7b0JBRUQsS0FBdUIsVUFBc0IsRUFBdEIsS0FBQSxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsRUFBdEIsY0FBc0IsRUFBdEIsSUFBc0IsRUFBRTt3QkFBMUMsSUFBTSxRQUFRLFNBQUE7d0JBQ2YsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTs0QkFDbEIsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO3lCQUNuQjtxQkFDSjtpQkFDSjtxQkFBTTtvQkFFSCxLQUFxQixVQUFvQixFQUFwQixLQUFBLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQXBCLGNBQW9CLEVBQXBCLElBQW9CLEVBQUU7d0JBQXRDLElBQU0sTUFBTSxTQUFBO3dCQUNiLElBQUksQ0FBQyw2QkFBNkIsRUFBRTs0QkFDaEMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtnQ0FDaEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzs2QkFDdkI7eUJBQ0o7d0JBQ0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7cUJBQy9CO29CQUVELEtBQXVCLFVBQXNCLEVBQXRCLEtBQUEsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsRUFBdEIsY0FBc0IsRUFBdEIsSUFBc0IsRUFBRTt3QkFBMUMsSUFBTSxRQUFRLFNBQUE7d0JBQ2YsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTs0QkFDbEIsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzt5QkFDekI7cUJBQ0o7aUJBQ0o7Z0JBRUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUNuQjtTQUNKO1FBQUMsT0FBTyxHQUFHLEVBQUU7WUFDVixPQUFPLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQzFEO0lBQ0wsQ0FBQztJQU1ELGtDQUFhLEdBQWI7UUFBQSxpQkFzRUM7UUFyRUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksVUFBVSxFQUFFLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFHbEMsSUFBSSxDQUFDLENBQUMsS0FBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDdkMsVUFBVSxHQUFHLENBQUMsT0FBTyxLQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO29CQUMzRSxLQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNyRCxVQUFVLEdBQUcsQ0FBQyxPQUFPLEtBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7b0JBQzNFLEtBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7YUFDeEQ7WUFFRCxJQUFNLFdBQVcsR0FBb0I7Z0JBQ2pDLG1CQUFtQixFQUFFLENBQUMsS0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLFVBQVUsQ0FBQztnQkFDM0UsbUJBQW1CLEVBQUUsQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksVUFBVSxDQUFDO2FBQzlFLENBQUM7WUFFRixPQUFPLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUUvRSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLFFBQVEsQ0FBQyxFQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUV0RSxJQUFJLFVBQVUsRUFBRTtvQkFDWixLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUU7d0JBQzVCLFNBQVMsRUFBRSxLQUFJLENBQUMsYUFBYSxDQUFDLElBQUk7cUJBQ3JDLENBQUMsQ0FBQztpQkFDTjtnQkFFRCxJQUFJLFVBQVUsRUFBRTtvQkFDWixLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUU7d0JBQzVCLFNBQVMsRUFBRSxLQUFJLENBQUMsYUFBYSxDQUFDLElBQUk7cUJBQ3JDLENBQUMsQ0FBQztpQkFDTjtnQkFFRCxLQUFJLENBQUMsRUFBRTtxQkFDRixXQUFXLEVBQUU7cUJBQ2IsSUFBSSxDQUFDLFVBQUEsS0FBSztvQkFDUCxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7b0JBQ25DLE9BQU8sS0FBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUMsQ0FBQyxDQUFDO3FCQUNELElBQUksQ0FBQztvQkFDRixJQUFNLGdCQUFnQixHQUFHLEtBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7b0JBRWxELElBQUksQ0FBQyxDQUFDLGdCQUFnQixFQUFFO3dCQUNwQixPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUM3RCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7cUJBQ2pDO3lCQUFNO3dCQUNILE1BQU0sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO3FCQUM5QztnQkFDTCxDQUFDLENBQUM7cUJBQ0QsS0FBSyxDQUFDLFVBQUEsS0FBSyxJQUFJLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO2FBRXRDO2lCQUFNO2dCQUdILEtBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLEtBQUs7b0JBQ3ZDLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztvQkFDbkMsT0FBTyxLQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QyxDQUFDLENBQUM7cUJBQ0csSUFBSSxDQUFDO29CQUNGLElBQU0sZ0JBQWdCLEdBQUcsS0FBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztvQkFDbEQsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEVBQUU7d0JBQ3BCLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQzdELE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztxQkFDakM7eUJBQU07d0JBQ0gsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7cUJBQzlDO2dCQUNMLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsVUFBQSxLQUFLLElBQUksT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7YUFDdEM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFNRCxrQ0FBYSxHQUFiLFVBQWMsU0FBaUIsRUFBRSwyQkFBb0M7UUFBckUsaUJBNEJDO1FBM0JHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFNLE1BQU0sR0FBOEI7Z0JBQ3RDLElBQUksRUFBRSxRQUFRO2dCQUNkLEdBQUcsRUFBRSxTQUFTO2FBQ2pCLENBQUM7WUFDRixPQUFPLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFFakUsSUFBSSxLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsS0FBSyxRQUFRLEVBQUU7Z0JBQ3JDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO2FBQ3pDO1lBQ0QsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBRXhCLElBQUksMkJBQTJCLEVBQUU7b0JBRTdCLFVBQVUsQ0FBQzt3QkFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLDZEQUE2RCxDQUFDLENBQUM7d0JBQzVFLEtBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsSUFBSSxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSyxJQUFJLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO29CQUN4SCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7aUJBQ1g7cUJBQU07b0JBRUgsS0FBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBQSxLQUFLLElBQUksT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7aUJBQ3ZIO2FBQ0o7aUJBQU07Z0JBRUgsS0FBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBTSxPQUFBLE9BQU8sRUFBRSxFQUFULENBQVMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFBLEtBQUssSUFBSSxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQzthQUM1RjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELG9DQUFlLEdBQWYsVUFBZ0IsWUFBNkI7UUFBN0MsaUJBcUJDO1FBcEJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzdELEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDOUMsUUFBUSxLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsRUFBRTtnQkFDNUIsS0FBSyxRQUFRO29CQUNULE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3JELE1BQU07Z0JBQ1YsS0FBSyxRQUFRO29CQUNULElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUU7d0JBQzdCLEtBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSyxJQUFJLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO3FCQUM3Rjt5QkFBTTt3QkFDSCxLQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUN6QyxPQUFPLEVBQUUsQ0FBQztxQkFDYjtvQkFDRCxNQUFNO2dCQUNWO29CQUNJLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3pDLE9BQU8sRUFBRSxDQUFDO2FBQ2pCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUwsaUJBQUM7QUFBRCxDQWxRQSxBQWtRQyxJQUFBO0FBbFFZLGdDQUFVO0FBcVF2QjtJQUF3QyxzQ0FBVTtJQUM5Qyw0QkFBWSxhQUFzQztRQUFsRCxpQkFHQztRQUZHLGFBQWEsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO1FBQ2hDLFFBQUEsa0JBQU0sYUFBYSxDQUFDLFNBQUM7O0lBQ3pCLENBQUM7SUFDTCx5QkFBQztBQUFELENBTEEsQUFLQyxDQUx1QyxVQUFVLEdBS2pEO0FBTFksZ0RBQWtCO0FBTy9CO0lBQXdDLHNDQUFVO0lBQzlDLDRCQUFZLGFBQXNDO1FBQWxELGlCQUdDO1FBRkcsYUFBYSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7UUFDaEMsUUFBQSxrQkFBTSxhQUFhLENBQUMsU0FBQzs7SUFDekIsQ0FBQztJQUNMLHlCQUFDO0FBQUQsQ0FMQSxBQUtDLENBTHVDLFVBQVUsR0FLakQ7QUFMWSxnREFBa0I7QUFPL0I7SUFBd0Msc0NBQVU7SUFDOUMsNEJBQVksYUFBc0M7UUFBbEQsaUJBR0M7UUFGRyxhQUFhLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztRQUNoQyxRQUFBLGtCQUFNLGFBQWEsQ0FBQyxTQUFDOztJQUN6QixDQUFDO0lBQ0wseUJBQUM7QUFBRCxDQUxBLEFBS0MsQ0FMdUMsVUFBVSxHQUtqRDtBQUxZLGdEQUFrQjs7Ozs7QUNqUy9CLG1DQUFzQztBQUV0QztJQWtDSSxxQkFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFoQzFCLHVCQUFrQixHQUFHLEtBQUssQ0FBQztRQUUzQixrQkFBYSxHQUFHLENBQUMsQ0FBQztRQUNsQixVQUFLLEdBQVE7WUFDakIsT0FBTyxFQUFFO2dCQUNMLEtBQUssRUFBRTtvQkFDSCxhQUFhLEVBQUUsQ0FBQztvQkFDaEIsZUFBZSxFQUFFLENBQUM7b0JBQ2xCLFdBQVcsRUFBRSxDQUFDO2lCQUNqQjtnQkFDRCxLQUFLLEVBQUU7b0JBQ0gsYUFBYSxFQUFFLENBQUM7b0JBQ2hCLGVBQWUsRUFBRSxDQUFDO29CQUNsQixXQUFXLEVBQUUsQ0FBQztvQkFDZCxhQUFhLEVBQUUsQ0FBQztvQkFDaEIsU0FBUyxFQUFFLENBQUM7aUJBQ2Y7YUFDSjtZQUNELFFBQVEsRUFBRTtnQkFDTixLQUFLLEVBQUU7b0JBQ0gsU0FBUyxFQUFFLENBQUM7b0JBQ1osV0FBVyxFQUFFLENBQUM7aUJBQ2pCO2dCQUNELEtBQUssRUFBRTtvQkFDSCxTQUFTLEVBQUUsQ0FBQztvQkFDWixXQUFXLEVBQUUsQ0FBQztvQkFDZCxhQUFhLEVBQUUsQ0FBQztvQkFDaEIsU0FBUyxFQUFFLENBQUM7aUJBQ2Y7YUFDSjtTQUNKLENBQUM7SUFFb0MsQ0FBQztJQUVoQywrQkFBUyxHQUFoQjtRQUNJLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDO0lBQ25DLENBQUM7SUFFTSxxQ0FBZSxHQUF0QjtRQUFBLGlCQXdCQztRQXRCRyxJQUFNLHVCQUF1QixHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUVqRixJQUFJLENBQUMsQ0FBQyx1QkFBdUIsRUFBRTtZQUczQixPQUFPLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRWxJLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7WUFFL0IsSUFBTSxpQkFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUM1RCxJQUFJLENBQUMsYUFBYSxHQUFHLGlCQUFlLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUVyRCxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWUsQ0FBQyxDQUFDLENBQUM7WUFFdEUsSUFBSSxDQUFDLHFCQUFxQixHQUFHLFdBQVcsQ0FBQztnQkFDckMsS0FBSSxDQUFDLHVCQUF1QixDQUFDLGlCQUFlLENBQUMsQ0FBQztZQUNsRCxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUU5QixPQUFPO1NBQ1Y7UUFFRCxPQUFPLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVNLHFDQUFlLEdBQXRCO1FBQ0ksSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDekIsYUFBYSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQzFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsMkNBQTJDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDOUk7SUFDTCxDQUFDO0lBRU0saURBQTJCLEdBQWxDO1FBQUEsaUJBNkRDO1FBNURHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxFQUNwRCxVQUFDLEtBQUs7Z0JBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN2RixJQUFJLGdCQUFnQixTQUFBLEVBQUUsaUJBQWlCLFNBQUEsRUFBRSxpQkFBaUIsU0FBQSxDQUFDO29CQUMzRCxJQUFNLGVBQWUsR0FBRyxFQUFFLENBQUM7b0JBQzNCLElBQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO29CQUM1QixLQUFLLElBQU0sR0FBRyxJQUFJLEtBQUssRUFBRTt3QkFDckIsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUN4QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLEVBQUU7NEJBQ2hDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO3lCQUNuQzs2QkFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssaUJBQWlCLEVBQUU7NEJBQ3hDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7eUJBQ3BDOzZCQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxtQkFBbUIsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxNQUFNLENBQUMsRUFBRTs0QkFDcEYsaUJBQWlCLEdBQUcsSUFBSSxDQUFDOzRCQUN6QixnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7NEJBQ3pDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQzt5QkFDOUM7cUJBQ0o7b0JBQ0QsSUFBSSxxQkFBbUIsR0FBRyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFDNUQsSUFBSSxDQUFDLENBQUMscUJBQW1CLEVBQUU7d0JBQ3ZCLElBQU0sUUFBUSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsd0JBQXdCLEVBQUUsQ0FBQzt3QkFDeEQsSUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQWtCOzRCQUM1QyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO2dDQUNqQixDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxxQkFBbUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO2dDQUN2RCxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxxQkFBbUIsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO2dDQUN4RCxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxxQkFBbUIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDaEUsQ0FBQyxDQUFDLENBQUM7d0JBQ0gscUJBQW1CLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLG1FQUFtRSxDQUFDO3FCQUNqSTt5QkFBTTt3QkFDSCxxQkFBbUIsR0FBRyxzRUFBc0UsQ0FBQztxQkFDaEc7b0JBRUQsSUFBSSxzQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO29CQUMvRCxJQUFJLENBQUMsQ0FBQyxzQkFBb0IsRUFBRTt3QkFDeEIsSUFBTSxRQUFRLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO3dCQUN6RCxJQUFNLElBQUksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBa0I7NEJBQzVDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0NBQ2pCLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLHNCQUFvQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7Z0NBQ3hELENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLHNCQUFvQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0NBQ3pELENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLHNCQUFvQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUNqRSxDQUFDLENBQUMsQ0FBQzt3QkFDSCxzQkFBb0IsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsd0VBQXdFLENBQUM7cUJBQ3ZJO3lCQUFNO3dCQUNILHNCQUFvQixHQUFHLHVFQUF1RSxDQUFDO3FCQUNsRztvQkFFRCxPQUFPLENBQUM7d0JBQ0osaUJBQWlCLG1CQUFBO3dCQUNqQixjQUFjLEVBQUUscUJBQW1CO3dCQUNuQyxlQUFlLEVBQUUsc0JBQW9CO3FCQUN4QyxDQUFDLENBQUM7aUJBQ047cUJBQU07b0JBQ0gsTUFBTSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7aUJBQ25FO1lBQ0wsQ0FBQyxFQUNELFVBQUMsS0FBSztnQkFDRixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEIsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyw2Q0FBdUIsR0FBL0IsVUFBZ0MsZUFBZTtRQUEvQyxpQkFpTkM7UUEvTUcsSUFBTSxRQUFRLEdBQUcsVUFBQyxJQUFJO1lBQ2xCLElBQU0sSUFBSSxHQUFtQixJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ2xELElBQU0sR0FBRyxHQUFXLGVBQWUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDO1lBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUU3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFFMUQsSUFBSSxDQUFDLGtCQUFrQixHQUFHO2dCQUN0QixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFO29CQUM5QyxPQUFPLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxHQUFHLEdBQUcsR0FBRyxjQUFjLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsaUJBQWlCLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7aUJBQzdKO1lBQ0wsQ0FBQyxDQUFDO1lBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUM7UUFFRixJQUFNLENBQUMsR0FBRyxVQUFDLEtBQUs7WUFFWixJQUFJLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUMxQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUMsSUFBSTtvQkFFZixJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7b0JBRWQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDO3dCQUM3QixDQUVJLElBQUksQ0FBQyxTQUFTLEtBQUssSUFBSTs0QkFDdkIsSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLOzRCQUN2QixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7NEJBQzdCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUN0QyxFQUFFO3dCQUVILElBQU0sUUFBUSxHQUFHLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7d0JBQ3RFLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO3dCQUUvQixJQUFNLE9BQU8sR0FBRzs0QkFDWixhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxhQUFhLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYTs0QkFDM0csTUFBTSxFQUFFLEdBQUc7NEJBQ1gsZUFBZSxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsZUFBZSxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWE7NEJBQ2pILFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEtBQUksQ0FBQyxhQUFhO3lCQUN4RyxDQUFDO3dCQUNGLElBQU0sS0FBSyxHQUFHOzRCQUNWLGFBQWEsRUFBRSxPQUFPOzRCQUN0QixNQUFNLEVBQUUsSUFBSTs0QkFDWixlQUFlLEVBQUUsU0FBUzs0QkFDMUIsV0FBVyxFQUFFLFNBQVM7eUJBQ3pCLENBQUM7d0JBQ0YsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLE9BQU8sRUFBRTs0QkFDNUIsT0FBTyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQzs0QkFDOUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQzs0QkFDbEcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxHQUFHLFFBQVEsQ0FBQzs0QkFDbEMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLFNBQVMsQ0FBQzs0QkFFL0IsS0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDOzRCQUM1RCxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7eUJBQ3ZEO3dCQUVELEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQzt3QkFDdEUsS0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO3dCQUMxRSxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7d0JBRWxFLElBQUksR0FBRzs0QkFDSCxZQUFZLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRTs0QkFDcEQsTUFBTSxFQUFFLGVBQWUsQ0FBQyxJQUFJOzRCQUM1QixXQUFXLEVBQUUsZUFBZSxDQUFDLFNBQVM7NEJBQ3RDLFFBQVEsRUFBRSxRQUFROzRCQUNsQixTQUFTLEVBQUUsUUFBUTs0QkFDbkIsYUFBYSxFQUFFLGtCQUFrQjs0QkFDakMsT0FBTyxFQUFFLEtBQUs7eUJBQ2pCLENBQUM7d0JBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLE9BQU8sQ0FBQzt3QkFFekIsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztxQkFFbEM7eUJBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssY0FBYyxDQUFDO3dCQUNyQyxDQUVJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSzs0QkFDdkIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQzdDLEVBQUU7d0JBRUgsSUFBTSxRQUFRLEdBQUcsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQzt3QkFFdkUsSUFBTSxPQUFPLEdBQUc7NEJBQ1osU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWE7NEJBQ2hHLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEtBQUksQ0FBQyxhQUFhO3lCQUN6RyxDQUFDO3dCQUNGLElBQU0sS0FBSyxHQUFHOzRCQUNWLFNBQVMsRUFBRSxPQUFPOzRCQUNsQixXQUFXLEVBQUUsU0FBUzt5QkFDekIsQ0FBQzt3QkFDRixJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssT0FBTyxFQUFFOzRCQUM1QixPQUFPLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDOzRCQUMvRyxLQUFLLENBQUMsZUFBZSxDQUFDLEdBQUcsUUFBUSxDQUFDOzRCQUVsQyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7eUJBQ2hFO3dCQUVELEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQzt3QkFDL0QsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO3dCQUVuRSxJQUFJLEdBQUc7NEJBQ0gsWUFBWSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLEVBQUU7NEJBQ3BELE1BQU0sRUFBRSxlQUFlLENBQUMsSUFBSTs0QkFDNUIsV0FBVyxFQUFFLGVBQWUsQ0FBQyxTQUFTOzRCQUN0QyxRQUFRLEVBQUUsUUFBUTs0QkFDbEIsU0FBUyxFQUFFLFFBQVE7NEJBQ25CLGFBQWEsRUFBRSxrQkFBa0I7NEJBQ2pDLE9BQU8sRUFBRSxLQUFLO3lCQUNqQixDQUFDO3dCQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxPQUFPLENBQUM7d0JBRXpCLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7cUJBQ2xDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2FBQ047aUJBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM5RixLQUFrQixVQUFrQixFQUFsQixLQUFBLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQWxCLGNBQWtCLEVBQWxCLElBQWtCLEVBQUU7b0JBQWpDLElBQU0sR0FBRyxTQUFBO29CQUNWLElBQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDeEIsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRTt3QkFFdEIsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO3dCQUVkLElBQUksZUFBZSxJQUFJLElBQUksSUFBSSxDQUMzQixDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssT0FBTyxJQUFJLGtCQUFrQixJQUFJLElBQUksQ0FBQzs0QkFDMUQsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLE9BQU8sSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLENBQ2xELEVBQUU7NEJBRUMsSUFBTSxRQUFRLEdBQUcsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQzs0QkFFdEUsSUFBTSxPQUFPLEdBQUc7Z0NBQ1osYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWE7Z0NBQzNHLE1BQU0sRUFBRSxJQUFJLENBQUMsa0JBQWtCO2dDQUMvQixlQUFlLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxlQUFlLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYTtnQ0FDakgsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWE7NkJBQ3hHLENBQUM7NEJBQ0YsSUFBTSxLQUFLLEdBQUc7Z0NBQ1YsYUFBYSxFQUFFLE9BQU87Z0NBQ3RCLE1BQU0sRUFBRSxJQUFJO2dDQUNaLGVBQWUsRUFBRSxTQUFTO2dDQUMxQixXQUFXLEVBQUUsU0FBUzs2QkFDekIsQ0FBQzs0QkFDRixJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssT0FBTyxFQUFFO2dDQUM1QixPQUFPLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDO2dDQUM5RyxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDO2dDQUN0RyxLQUFLLENBQUMsZUFBZSxDQUFDLEdBQUcsUUFBUSxDQUFDO2dDQUNsQyxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsU0FBUyxDQUFDO2dDQUUvQixLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7Z0NBQzVELEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQzs2QkFDM0Q7NEJBRUQsS0FBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDOzRCQUN0RSxLQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7NEJBQzFFLEtBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQzs0QkFFbEUsSUFBSSxHQUFHO2dDQUNILFlBQVksRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxFQUFFO2dDQUNwRCxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUk7Z0NBQzVCLFdBQVcsRUFBRSxlQUFlLENBQUMsU0FBUztnQ0FDdEMsUUFBUSxFQUFFLFFBQVE7Z0NBQ2xCLFNBQVMsRUFBRSxRQUFRO2dDQUNuQixhQUFhLEVBQUUsa0JBQWtCO2dDQUNqQyxPQUFPLEVBQUUsS0FBSzs2QkFDakIsQ0FBQzs0QkFDRixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsT0FBTyxDQUFDOzRCQUV6QixRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO3lCQUNsQzs2QkFBTSxJQUFJLFdBQVcsSUFBSSxJQUFJLEVBQUU7NEJBRTVCLElBQU0sUUFBUSxHQUFHLGtCQUFrQixHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7NEJBRXZFLElBQU0sT0FBTyxHQUFHO2dDQUNaLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUksQ0FBQyxhQUFhO2dDQUNoRyxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYTs2QkFDekcsQ0FBQzs0QkFDRixJQUFNLEtBQUssR0FBRztnQ0FDVixTQUFTLEVBQUUsT0FBTztnQ0FDbEIsV0FBVyxFQUFFLFNBQVM7NkJBQ3pCLENBQUM7NEJBQ0YsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLE9BQU8sRUFBRTtnQ0FDNUIsT0FBTyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQztnQ0FDL0csS0FBSyxDQUFDLGVBQWUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztnQ0FFbEMsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDOzZCQUNoRTs0QkFFRCxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7NEJBQy9ELEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQzs0QkFFbkUsSUFBSSxHQUFHO2dDQUNILFlBQVksRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxFQUFFO2dDQUNwRCxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUk7Z0NBQzVCLFdBQVcsRUFBRSxlQUFlLENBQUMsU0FBUztnQ0FDdEMsUUFBUSxFQUFFLFFBQVE7Z0NBQ2xCLFNBQVMsRUFBRSxRQUFRO2dDQUNuQixhQUFhLEVBQUUsa0JBQWtCO2dDQUNqQyxPQUFPLEVBQUUsS0FBSzs2QkFDakIsQ0FBQzs0QkFDRixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsT0FBTyxDQUFDOzRCQUV6QixRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO3lCQUNsQztxQkFDSjtpQkFDSjthQUNKO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxDQUFDLEVBQUUsVUFBQyxLQUFLLElBQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JHLENBQUM7SUFFTyx1Q0FBaUIsR0FBekIsVUFBMEIsUUFBUTtRQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RCLElBQU0sY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUUxQixJQUFJLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUEsR0FBRztnQkFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sUUFBUSxDQUFDO1NBQ25CO1FBRUQsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFBLE1BQU07WUFDNUIsSUFBTSxhQUFhLEdBQUc7Z0JBQ2xCLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtnQkFDYixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7Z0JBQzNCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTthQUNwQixDQUFDO1lBQ0YsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUk7Z0JBQ3hCLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1lBQ0gsY0FBYyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-insecure-angular/package-lock.json b/openvidu-insecure-angular/package-lock.json index c838e903c..7bccc42bc 100644 --- a/openvidu-insecure-angular/package-lock.json +++ b/openvidu-insecure-angular/package-lock.json @@ -1,6 +1,6 @@ { "name": "openvidu-insecure-angular", - "version": "2.9.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -437,18 +437,18 @@ } }, "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -505,9 +505,9 @@ } }, "@types/node": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.4.tgz", - "integrity": "sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw==", + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", "dev": true }, "@types/source-list-map": { @@ -753,9 +753,9 @@ } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", "dev": true }, "acorn-dynamic-import": { @@ -765,9 +765,9 @@ "dev": true }, "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -801,9 +801,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "dev": true }, "amdefine": { @@ -879,9 +879,9 @@ } }, "arg": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", - "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", "dev": true }, "argparse": { @@ -1030,12 +1030,12 @@ "dev": true }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "async-each": { @@ -1510,14 +1510,14 @@ } }, "browserslist": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.1.tgz", - "integrity": "sha512-1MC18ooMPRG2UuVFJTHFIAkk6mpByJfxCrnUyvSlu/hyQSFHMrlhM02SzNuCV+quTP4CKmqtOMAIjrifrpBJXQ==", + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000971", - "electron-to-chromium": "^1.3.137", - "node-releases": "^1.1.21" + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" } }, "buffer": { @@ -1611,6 +1611,30 @@ "unset-value": "^1.0.0" } }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", @@ -1630,9 +1654,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000973", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000973.tgz", - "integrity": "sha512-/F3t/Yo8LEdRSEPCmI15fLu5vepVh9UCg/9inJXF5AAfW7xRRJkbaM2ut52iRMQMnGCLQouLbFdbOA+VEFOIsg==", + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000986.tgz", + "integrity": "sha512-pM+LnkoAX0+QnIH3tpW5EnkmfpEoqOD8FAcoBvsl3Xh6DXkgctiCxeCbXphP/k3XJtJzm+zOAJbi6U6IVkpWZQ==", "dev": true }, "canonical-path": { @@ -1698,9 +1722,9 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "chrome-trace-event": { @@ -2062,15 +2086,15 @@ "dev": true }, "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { + "import-fresh": "^2.0.0", "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" }, "dependencies": { "parse-json": { @@ -2481,15 +2505,15 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.144", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.144.tgz", - "integrity": "sha512-jNRFJpfNrYm5uJ4x0q9oYMOfbL0JPOlkNli8GS/5zEmCjnE5jAtoCo4BYajHiqSPqEeAjtTdItL4p7EZw+jSfg==", + "version": "1.3.203", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.203.tgz", + "integrity": "sha512-Z1FjJKEBhYrCNmnususVk8khiBabVI/bSJB/295V4ghVt4MFmtbP+mXgRZLQZinEBI469U6FtiGgpXnlLs6qiQ==", "dev": true }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -2567,9 +2591,9 @@ } }, "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-promisify": { @@ -2813,9 +2837,9 @@ } }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -3034,9 +3058,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -3830,9 +3854,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", "dev": true }, "handle-thing": { @@ -3991,12 +4015,20 @@ "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } } }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", "dev": true }, "http-proxy": { @@ -4062,12 +4094,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", "dev": true, "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" }, "dependencies": { @@ -4081,9 +4113,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -4149,6 +4181,16 @@ "import-from": "^2.1.0" } }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, "import-from": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", @@ -4245,12 +4287,6 @@ "repeating": "^2.0.0" } }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4262,9 +4298,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ini": { @@ -4928,9 +4964,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash.assign": { @@ -4953,9 +4989,9 @@ "dev": true }, "lodash.mergewith": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true, "optional": true }, @@ -4966,9 +5002,9 @@ "dev": true }, "loglevel": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.2.tgz", - "integrity": "sha512-Jt2MHrCNdtIe1W6co3tF5KXGRkzF+TYffiQstfXa04mrss9IKXzAAXYWak8LbZseAQY03sH2GzMCMU0ZOUc9bg==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", + "integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==", "dev": true }, "loose-envify": { @@ -5002,9 +5038,9 @@ } }, "magic-string": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", - "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", "dev": true, "requires": { "sourcemap-codec": "^1.4.4" @@ -5026,17 +5062,17 @@ "dev": true }, "make-fetch-happen": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz", - "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.2.tgz", + "integrity": "sha512-YMJrAjHSb/BordlsDEcVcPyTbiJKkzqMf48N8dAJZT9Zjctrkb6Yg4TY9Sq2AwSIQJFn5qBBKVTYt3vP5FMIHA==", "dev": true, "requires": { "agentkeepalive": "^3.4.1", - "cacache": "^11.0.1", + "cacache": "^11.3.3", "http-cache-semantics": "^3.8.1", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", + "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "node-fetch-npm": "^2.0.2", "promise-retry": "^1.1.1", @@ -5045,36 +5081,48 @@ }, "dependencies": { "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "dev": true, "requires": { - "bluebird": "^3.5.3", + "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "graceful-fs": "^4.1.15", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - } + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" } }, "mississippi": { @@ -5364,9 +5412,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -5553,9 +5601,9 @@ } }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { "assert": "^1.1.1", @@ -5568,7 +5616,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -5580,7 +5628,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" }, "dependencies": { "punycode": { @@ -5592,9 +5640,9 @@ } }, "node-releases": { - "version": "1.1.22", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.22.tgz", - "integrity": "sha512-O6XpteBuntW1j86mw6LlovBIwTe+sO2+7vi9avQffNeIW4upgnaCVm6xrBWH+KATz7mNNRNNeEpuWB7dT6Cr3w==", + "version": "1.1.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.26.tgz", + "integrity": "sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ==", "dev": true, "requires": { "semver": "^5.3.0" @@ -5714,9 +5762,9 @@ } }, "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", + "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -5735,17 +5783,34 @@ } }, "npm-registry-fetch": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz", - "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.1.tgz", + "integrity": "sha512-VQCEZlydXw4AwLROAXWUR7QDfe2Y8Id/vpAgp6TI1/H78a4SiQ1kQrKZALm5/zxM5n4HIi+aYb+idUAV/RuY0Q==", "dev": true, "requires": { "JSONStream": "^1.3.4", "bluebird": "^3.5.1", "figgy-pudding": "^3.4.1", - "lru-cache": "^4.1.3", - "make-fetch-happen": "^4.0.1", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^4.0.2", "npm-package-arg": "^6.1.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } } }, "npm-run-path": { @@ -5901,11 +5966,11 @@ } }, "openvidu-browser": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.10.0.tgz", - "integrity": "sha512-D+Eww0fh4omsNeeNSelj37s/mmvCe18MhtNsoaWXRSKclBWPrDpab6Ct4wonH5zpQK5sVCWG+KwEnDoBd1Y0Vg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.11.0.tgz", + "integrity": "sha512-dXnzHA9gf0Fhl88YijmPbFT/d7ERUHOMrqGObVeDc5NvG/7y2HCFafb/42O/mZ86IkBZnmqSrl6Q63aNlUZ2iA==", "requires": { - "@types/node": "12.0.3", + "@types/node": "12.6.8", "@types/platform": "1.3.2", "freeice": "2.2.2", "hark": "1.2.3", @@ -5915,93 +5980,38 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" - }, - "@types/fs-extra": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz", - "integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", - "requires": { - "handlebars": "*" - } - }, - "@types/highlight.js": { - "version": "9.12.3", - "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", - "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==" - }, - "@types/lodash": { - "version": "4.14.132", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.132.tgz", - "integrity": "sha512-RNUU1rrh85NgUJcjOOr96YXr+RHwInGbaQCZmlitqOaCKXffj8bh+Zxwuq5rjDy5OgzFldDVoqk4pyLEDiwxIw==" - }, - "@types/marked": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz", - "integrity": "sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==" - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.3.tgz", - "integrity": "sha512-zkOxCS/fA+3SsdA+9Yun0iANxzhQRiNwTvJSr6N95JhuJ/x27z9G2URx1Jpt3zYFfCGUXZGL5UDxt5eyLE7wgw==" + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==" }, "@types/platform": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.2.tgz", "integrity": "sha512-Tn6OuJDAG7bJbyi4R7HqcxXp1w2lmIxVXqyNhPt1Bm0FO2EWIi3CI87JVzF7ncqK0ZMPuUycS3wTMIk85EeF1Q==" }, - "@types/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==", - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -6017,9 +6027,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -6038,9 +6048,9 @@ } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, "amdefine": { "version": "1.0.1", @@ -6214,6 +6224,14 @@ "postcss": "~4.1.12" } }, + "backbone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", + "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", + "requires": { + "underscore": ">=1.8.3" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -6365,9 +6383,9 @@ } }, "browserify": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", - "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", + "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -6562,9 +6580,9 @@ } }, "caniuse-db": { - "version": "1.0.30000971", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000971.tgz", - "integrity": "sha512-ubSZfYXO2KMYtCVmDez82mjodeZa+mBYWAnBMAmFBPAn4C2PY4SD0eC/diYQD4Rj1K+WNdp0vr0JDtm0SQ6GNg==" + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000986.tgz", + "integrity": "sha512-8SKJ12AFwG0ReMjPwRH+keFsX/ucw2bi6LC7upeXBvxjgrMqHaTxgYhkRGm+eOwUWvVcqXDgqM7QNlRJMhvXZg==" }, "chalk": { "version": "2.4.2", @@ -6809,9 +6827,9 @@ }, "dependencies": { "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" } } }, @@ -6992,9 +7010,9 @@ } }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -7310,11 +7328,11 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -7893,9 +7911,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "grunt": { "version": "1.0.4", @@ -8149,11 +8167,11 @@ }, "dependencies": { "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } } } @@ -8217,11 +8235,11 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "chalk": { @@ -8431,9 +8449,9 @@ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=" }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "https-browserify": { "version": "1.0.0", @@ -8471,9 +8489,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -8683,6 +8701,11 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-base64": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", @@ -8793,9 +8816,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.memoize": { "version": "3.0.4", @@ -8816,6 +8839,11 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" }, + "lunr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.6.tgz", + "integrity": "sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -8843,9 +8871,9 @@ } }, "marked": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", - "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" }, "maxmin": { "version": "2.1.0", @@ -8983,9 +9011,9 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -9417,9 +9445,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -9533,6 +9561,11 @@ "util-deprecate": "~1.0.1" }, "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -9603,9 +9636,9 @@ } }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } @@ -9647,9 +9680,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-json-parse": { "version": "1.0.1", @@ -9680,9 +9713,9 @@ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -9892,9 +9925,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -9978,6 +10011,13 @@ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -10077,9 +10117,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -10156,14 +10196,14 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", + "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -10171,7 +10211,7 @@ "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -10206,50 +10246,43 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.14.2.tgz", - "integrity": "sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ==", - "requires": { - "@types/fs-extra": "^5.0.3", - "@types/handlebars": "^4.0.38", - "@types/highlight.js": "^9.12.3", - "@types/lodash": "^4.14.110", - "@types/marked": "^0.4.0", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.15.0.tgz", + "integrity": "sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw==", + "requires": { "@types/minimatch": "3.0.3", - "@types/shelljs": "^0.8.0", - "fs-extra": "^7.0.0", - "handlebars": "^4.0.6", - "highlight.js": "^9.13.1", - "lodash": "^4.17.10", - "marked": "^0.4.0", + "fs-extra": "^8.1.0", + "handlebars": "^4.1.2", + "highlight.js": "^9.15.8", + "lodash": "^4.17.15", + "marked": "^0.7.0", "minimatch": "^3.0.0", - "progress": "^2.0.0", - "shelljs": "^0.8.2", - "typedoc-default-themes": "^0.5.0", - "typescript": "3.2.x" - }, - "dependencies": { - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==" - } + "progress": "^2.0.3", + "shelljs": "^0.8.3", + "typedoc-default-themes": "^0.6.0", + "typescript": "3.5.x" } }, "typedoc-default-themes": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz", - "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.6.0.tgz", + "integrity": "sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw==", + "requires": { + "backbone": "^1.4.0", + "jquery": "^3.4.1", + "lunr": "^2.3.6", + "underscore": "^1.9.1" + } }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==" + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==" }, "uglify-js": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", - "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" @@ -10284,6 +10317,11 @@ "xtend": "^4.0.1" } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -10294,35 +10332,14 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "universalify": { @@ -10408,6 +10425,13 @@ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "util-deprecate": { @@ -10443,11 +10467,12 @@ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -10465,9 +10490,9 @@ } }, "wildemitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.0.tgz", - "integrity": "sha1-Kd06ctaZw+J53QIcPNIVC4LJohE=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.1.tgz", + "integrity": "sha512-UMmSUoIQSir+XbBpTxOTS53uJ8s/lVhADCkEbhfRjUGFDPme/XGOb0sBWLx5sTz7Wx/2+TlAw1eK9O5lw5PiEw==" }, "wolfy87-eventemitter": { "version": "5.2.6", @@ -10499,9 +10524,9 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } }, @@ -10645,25 +10670,41 @@ }, "dependencies": { "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "dev": true, "requires": { - "bluebird": "^3.5.3", + "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "graceful-fs": "^4.1.15", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + } } }, "get-stream": { @@ -10722,9 +10763,9 @@ } }, "tar": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.9.tgz", - "integrity": "sha512-xisFa7Q2i3HOgfn+nmnWLGHD6Tm23hxjkx6wwGmgxkJFr6wxwXnJOdJYcZjL453PSdF0+bemO03+flAzkIdLBQ==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", "dev": true, "requires": { "chownr": "^1.1.1", @@ -10803,9 +10844,9 @@ "dev": true }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "path-dirname": { @@ -10910,9 +10951,9 @@ } }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", + "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", "dev": true, "requires": { "async": "^1.5.2", @@ -10966,12 +11007,12 @@ } }, "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "dev": true, "requires": { - "cosmiconfig": "^4.0.0", + "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" } }, @@ -11000,9 +11041,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "promise": { @@ -11063,9 +11104,9 @@ "dev": true }, "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", "dev": true, "optional": true }, @@ -11444,12 +11485,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -11749,6 +11784,12 @@ "statuses": ">= 1.4.0 < 2" } }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -11776,9 +11817,9 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -12030,18 +12071,18 @@ } }, "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -12064,6 +12105,17 @@ "requires": { "agent-base": "~4.2.1", "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } } }, "source-list-map": { @@ -12126,9 +12178,9 @@ "dev": true }, "sourcemap-codec": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", - "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", "dev": true }, "spdx-correct": { @@ -12158,15 +12210,15 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -12186,9 +12238,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -12217,9 +12269,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "readable-stream": { @@ -12555,22 +12607,22 @@ }, "dependencies": { "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "dev": true, "requires": { - "bluebird": "^3.5.3", + "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "graceful-fs": "^4.1.15", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" @@ -12596,6 +12648,20 @@ "locate-path": "^3.0.0" } }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -12878,9 +12944,9 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tslint": { "version": "5.16.0", @@ -12958,38 +13024,15 @@ "dev": true }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unique-filename": { @@ -13002,9 +13045,9 @@ } }, "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, "requires": { "imurmurhash": "^0.1.4" @@ -13118,6 +13161,14 @@ "dev": true, "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } } }, "util-deprecate": { @@ -13176,13 +13227,10 @@ } }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true }, "watchpack": { "version": "1.6.0", @@ -13288,9 +13336,9 @@ }, "dependencies": { "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true } } @@ -13463,15 +13511,15 @@ } }, "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "os-locale": { @@ -13645,12 +13693,13 @@ } }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -13724,9 +13773,9 @@ "dev": true }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "y18n": { diff --git a/openvidu-insecure-angular/package.json b/openvidu-insecure-angular/package.json index 38f371363..614182440 100644 --- a/openvidu-insecure-angular/package.json +++ b/openvidu-insecure-angular/package.json @@ -1,6 +1,6 @@ { "name": "openvidu-insecure-angular", - "version": "2.10.0", + "version": "2.11.0", "license": "Apache-2.0", "scripts": { "start": "ng serve" @@ -14,7 +14,7 @@ "@angular/platform-browser": "7.2.14", "@angular/platform-browser-dynamic": "7.2.14", "core-js": "2.6.5", - "openvidu-browser": "2.10.0", + "openvidu-browser": "2.11.0", "zone.js": "0.9.0" }, "devDependencies": { diff --git a/openvidu-insecure-js/docker/Dockerfile b/openvidu-insecure-js/docker/Dockerfile index da049dc28..8c5740a7e 100644 --- a/openvidu-insecure-js/docker/Dockerfile +++ b/openvidu-insecure-js/docker/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:16.04 LABEL maintainer="openvidu@gmail.com" # Install Kurento Media Server (KMS) -RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.10.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ +RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.11.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83 \ && apt-get update \ && apt-get -y install kurento-media-server \ diff --git a/openvidu-insecure-js/web/index.html b/openvidu-insecure-js/web/index.html index aebac6802..fc5e7c337 100644 --- a/openvidu-insecure-js/web/index.html +++ b/openvidu-insecure-js/web/index.html @@ -14,7 +14,7 @@ - + diff --git a/openvidu-insecure-js/web/openvidu-browser-2.10.0.js b/openvidu-insecure-js/web/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-insecure-js/web/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-insecure-js/web/openvidu-browser-2.11.0.js b/openvidu-insecure-js/web/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-insecure-js/web/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-insecure-react/package-lock.json b/openvidu-insecure-react/package-lock.json index 39fbb0b50..b3e83b582 100644 --- a/openvidu-insecure-react/package-lock.json +++ b/openvidu-insecure-react/package-lock.json @@ -1,13 +1,13 @@ { "name": "openvidu-insecure-react", - "version": "2.9.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } @@ -42,9 +42,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "5.7.0", @@ -54,13 +54,13 @@ } }, "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", "requires": { - "@babel/types": "^7.4.4", + "@babel/types": "^7.5.5", "jsesc": "^2.5.1", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "source-map": "^0.5.0", "trim-right": "^1.0.1" } @@ -102,26 +102,26 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", - "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz", + "integrity": "sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4" } }, "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { @@ -160,11 +160,11 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.5.5" } }, "@babel/helper-module-imports": { @@ -176,16 +176,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { @@ -202,11 +202,11 @@ "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/helper-remap-async-to-generator": { @@ -222,14 +222,14 @@ } }, "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" } }, "@babel/helper-simple-access": { @@ -261,19 +261,19 @@ } }, "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", "requires": { "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -281,9 +281,9 @@ } }, "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", @@ -314,6 +314,15 @@ "@babel/plugin-syntax-decorators": "^7.2.0" } }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", + "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0" + } + }, "@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", @@ -324,9 +333,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", - "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", + "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" @@ -432,9 +441,9 @@ } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -450,25 +459,25 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", + "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", + "@babel/helper-define-map": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4", "globals": "^11.1.0" } @@ -482,9 +491,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -500,9 +509,9 @@ } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", + "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -559,31 +568,34 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", + "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", "requires": { "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", "requires": { "@babel/helper-module-transforms": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", - "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", + "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", "requires": { "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { @@ -612,12 +624,12 @@ } }, "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" + "@babel/helper-replace-supers": "^7.5.5" } }, "@babel/plugin-transform-parameters": { @@ -639,9 +651,9 @@ } }, "@babel/plugin-transform-react-constant-elements": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.2.0.tgz", - "integrity": "sha512-YYQFg6giRFMsZPKUM9v+VcHOdfSQdz9jHCx3akAi3UYgyjndmdYGSXylQ/V+HswQt4fL8IklchD9HTsaOCrWQQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.5.0.tgz", + "integrity": "sha512-c5Ba8cpybZFp1Izkf2sWGuNjOxoQ32tFgBvvYvwGhi4+9f6vGiSK9Gex4uVuO/Va6YJFu41aAh1MzMjUWkp0IQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -675,9 +687,9 @@ } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", - "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", + "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0" @@ -760,10 +772,11 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz", - "integrity": "sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz", + "integrity": "sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==", "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.5", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-typescript": "^7.2.0" } @@ -779,42 +792,44 @@ } }, "@babel/preset-env": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz", - "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", + "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-dynamic-import": "^7.5.0", "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.4.4", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-json-strings": "^7.2.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.4.4", + "@babel/plugin-transform-async-to-generator": "^7.5.0", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.4.4", - "@babel/plugin-transform-classes": "^7.4.4", + "@babel/plugin-transform-block-scoping": "^7.5.5", + "@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.4.4", + "@babel/plugin-transform-destructuring": "^7.5.0", "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.5.0", "@babel/plugin-transform-exponentiation-operator": "^7.2.0", "@babel/plugin-transform-for-of": "^7.4.4", "@babel/plugin-transform-function-name": "^7.4.4", "@babel/plugin-transform-literals": "^7.2.0", "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@babel/plugin-transform-modules-systemjs": "^7.4.4", + "@babel/plugin-transform-modules-amd": "^7.5.0", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/plugin-transform-modules-systemjs": "^7.5.0", "@babel/plugin-transform-modules-umd": "^7.2.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-object-super": "^7.5.5", "@babel/plugin-transform-parameters": "^7.4.4", "@babel/plugin-transform-property-literals": "^7.2.0", "@babel/plugin-transform-regenerator": "^7.4.5", @@ -825,7 +840,7 @@ "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.4.4", + "@babel/types": "^7.5.5", "browserslist": "^4.6.0", "core-js-compat": "^3.1.1", "invariant": "^2.2.2", @@ -880,19 +895,19 @@ } }, "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" }, "dependencies": { "debug": { @@ -904,19 +919,19 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, @@ -950,21 +965,34 @@ "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==" }, "@hapi/joi": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.0.3.tgz", - "integrity": "sha512-z6CesJ2YBwgVCi+ci8SI8zixoj8bGFn/vZb9MBPbSyoxsS2PnWYjHcyTM17VLK6tx64YVK38SDIh10hJypB+ig==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.0.tgz", + "integrity": "sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==", "requires": { "@hapi/address": "2.x.x", "@hapi/hoek": "6.x.x", + "@hapi/marker": "1.x.x", "@hapi/topo": "3.x.x" } }, + "@hapi/marker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@hapi/marker/-/marker-1.0.0.tgz", + "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA==" + }, "@hapi/topo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.0.tgz", - "integrity": "sha512-gZDI/eXOIk8kP2PkUKjWu9RW8GGVd2Hkgjxyr/S7Z+JF+0mr7bAlbw+DkTRxnD580o8Kqxlnba9wvqp5aOHBww==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.2.tgz", + "integrity": "sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA==", "requires": { - "@hapi/hoek": "6.x.x" + "@hapi/hoek": "8.x.x" + }, + "dependencies": { + "@hapi/hoek": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.1.0.tgz", + "integrity": "sha512-b1J4jxYnW+n6lC91V6Pqg9imP9BZq0HNCeM+3sbXg05rQsE9cGYrKFpZjyztVesGmNRE6R+QaEoWGATeIiUVjA==" + } } }, "@jest/console": { @@ -1211,9 +1239,9 @@ "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==" }, "@svgr/babel-plugin-svg-dynamic-title": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.0.tgz", - "integrity": "sha512-3eI17Pb3jlg3oqV4Tie069n1SelYKBUpI90txDcnBWk4EGFW+YQGyQjy6iuJAReH0RnpUJ9jUExrt/xniGvhqw==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.1.tgz", + "integrity": "sha512-p6z6JJroP989jHWcuraeWpzdejehTmLUpyC9smhTBWyPN0VVGe2phbYxpPTV7Vh8XzmFrcG55idrnfWn/2oQEw==" }, "@svgr/babel-plugin-svg-em-dimensions": { "version": "4.2.0", @@ -1231,59 +1259,98 @@ "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==" }, "@svgr/babel-preset": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.0.tgz", - "integrity": "sha512-Lgy1RJiZumGtv6yJroOxzFuL64kG/eIcivJQ7y9ljVWL+0QXvFz4ix1xMrmjMD+rpJWwj50ayCIcFelevG/XXg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.1.tgz", + "integrity": "sha512-rPFKLmyhlh6oeBv3j2vEAj2nd2QbWqpoJLKzBLjwQVt+d9aeXajVaPNEqrES2spjXKR4OxfgSs7U0NtmAEkr0Q==", "requires": { "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0", "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0", "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0", "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0", - "@svgr/babel-plugin-svg-dynamic-title": "^4.3.0", + "@svgr/babel-plugin-svg-dynamic-title": "^4.3.1", "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0", "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0", "@svgr/babel-plugin-transform-svg-component": "^4.2.0" } }, "@svgr/core": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.0.tgz", - "integrity": "sha512-Ycu1qrF5opBgKXI0eQg3ROzupalCZnSDETKCK/3MKN4/9IEmt3jPX/bbBjftklnRW+qqsCEpO0y/X9BTRw2WBg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.2.tgz", + "integrity": "sha512-N+tP5CLFd1hP9RpO83QJPZY3NL8AtrdqNbuhRgBkjE/49RnMrrRsFm1wY8pueUfAGvzn6tSXUq29o6ah8RuR5w==", "requires": { - "@svgr/plugin-jsx": "^4.3.0", + "@svgr/plugin-jsx": "^4.3.2", "camelcase": "^5.3.1", - "cosmiconfig": "^5.2.0" + "cosmiconfig": "^5.2.1" } }, "@svgr/hast-util-to-babel-ast": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.2.0.tgz", - "integrity": "sha512-IvAeb7gqrGB5TH9EGyBsPrMRH/QCzIuAkLySKvH2TLfLb2uqk98qtJamordRQTpHH3e6TORfBXoTo7L7Opo/Ow==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz", + "integrity": "sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==", "requires": { - "@babel/types": "^7.4.0" + "@babel/types": "^7.4.4" } }, "@svgr/plugin-jsx": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.0.tgz", - "integrity": "sha512-0ab8zJdSOTqPfjZtl89cjq2IOmXXUYV3Fs7grLT9ur1Al3+x3DSp2+/obrYKUGbQUnLq96RMjSZ7Icd+13vwlQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.2.tgz", + "integrity": "sha512-+1GW32RvmNmCsOkMoclA/TppNjHPLMnNZG3/Ecscxawp051XJ2MkO09Hn11VcotdC2EPrDfT8pELGRo+kbZ1Eg==", "requires": { - "@babel/core": "^7.4.3", - "@svgr/babel-preset": "^4.3.0", - "@svgr/hast-util-to-babel-ast": "^4.2.0", - "rehype-parse": "^6.0.0", - "unified": "^7.1.0", - "vfile": "^4.0.0" + "@babel/core": "^7.4.5", + "@svgr/babel-preset": "^4.3.1", + "@svgr/hast-util-to-babel-ast": "^4.3.2", + "svg-parser": "^2.0.0" + }, + "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } } }, "@svgr/plugin-svgo": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.2.0.tgz", - "integrity": "sha512-zUEKgkT172YzHh3mb2B2q92xCnOAMVjRx+o0waZ1U50XqKLrVQ/8dDqTAtnmapdLsGurv8PSwenjLCUpj6hcvw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz", + "integrity": "sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==", "requires": { - "cosmiconfig": "^5.2.0", + "cosmiconfig": "^5.2.1", "merge-deep": "^3.0.2", - "svgo": "^1.2.1" + "svgo": "^1.2.2" } }, "@svgr/webpack": { @@ -1331,9 +1398,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", - "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", + "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", "requires": { "@babel/types": "^7.3.0" } @@ -1360,11 +1427,6 @@ "@types/istanbul-lib-report": "*" } }, - "@types/node": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.4.tgz", - "integrity": "sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw==" - }, "@types/q": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", @@ -1375,30 +1437,6 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" }, - "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" - }, - "@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "requires": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "@types/vfile-message": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz", - "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==", - "requires": { - "@types/node": "*", - "@types/unist": "*" - } - }, "@types/yargs": { "version": "12.0.12", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.12.tgz", @@ -1624,9 +1662,9 @@ } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -1648,9 +1686,9 @@ "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, "address": { "version": "1.0.3", @@ -1658,9 +1696,9 @@ "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==" }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1674,9 +1712,9 @@ "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "ajv-keywords": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" }, "alphanum-sort": { "version": "1.0.2", @@ -1907,17 +1945,24 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz", - "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", + "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", "requires": { - "browserslist": "^4.6.1", - "caniuse-lite": "^1.0.30000971", + "browserslist": "^4.6.3", + "caniuse-lite": "^1.0.30000980", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.16", - "postcss-value-parser": "^3.3.1" + "postcss": "^7.0.17", + "postcss-value-parser": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz", + "integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==" + } } }, "aws-sign2": { @@ -2057,18 +2102,19 @@ } }, "babel-plugin-dynamic-import-node": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz", - "integrity": "sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", "requires": { "object.assign": "^4.1.0" } }, "babel-plugin-istanbul": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz", - "integrity": "sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", "requires": { + "@babel/helper-plugin-utils": "^7.0.0", "find-up": "^3.0.0", "istanbul-lib-instrument": "^3.3.0", "test-exclude": "^5.2.3" @@ -2182,6 +2228,15 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.2.0.tgz", + "integrity": "sha512-YYQFg6giRFMsZPKUM9v+VcHOdfSQdz9jHCx3akAi3UYgyjndmdYGSXylQ/V+HswQt4fL8IklchD9HTsaOCrWQQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/preset-env": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.3.tgz", @@ -2237,6 +2292,14 @@ "semver": "^5.5.0" } }, + "babel-plugin-dynamic-import-node": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz", + "integrity": "sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==", + "requires": { + "object.assign": "^4.1.0" + } + }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -2270,11 +2333,6 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, - "bail": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", - "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2555,19 +2613,19 @@ } }, "browserslist": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.1.tgz", - "integrity": "sha512-1MC18ooMPRG2UuVFJTHFIAkk6mpByJfxCrnUyvSlu/hyQSFHMrlhM02SzNuCV+quTP4CKmqtOMAIjrifrpBJXQ==", + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", "requires": { - "caniuse-lite": "^1.0.30000971", - "electron-to-chromium": "^1.3.137", - "node-releases": "^1.1.21" + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" } }, "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", "requires": { "node-int64": "^0.4.0" } @@ -2608,21 +2666,21 @@ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "requires": { - "bluebird": "^3.5.3", + "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "graceful-fs": "^4.1.15", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" @@ -2696,9 +2754,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000973", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000973.tgz", - "integrity": "sha512-/F3t/Yo8LEdRSEPCmI15fLu5vepVh9UCg/9inJXF5AAfW7xRRJkbaM2ut52iRMQMnGCLQouLbFdbOA+VEFOIsg==" + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000986.tgz", + "integrity": "sha512-pM+LnkoAX0+QnIH3tpW5EnkmfpEoqOD8FAcoBvsl3Xh6DXkgctiCxeCbXphP/k3XJtJzm+zOAJbi6U6IVkpWZQ==" }, "capture-exit": { "version": "2.0.0", @@ -2718,11 +2776,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "ccount": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", - "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==" - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3246,9 +3299,9 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" }, "chrome-trace-event": { "version": "1.0.2", @@ -3411,11 +3464,6 @@ "delayed-stream": "~1.0.0" } }, - "comma-separated-tokens": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz", - "integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==" - }, "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", @@ -3567,26 +3615,26 @@ "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==" }, "core-js-compat": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.3.tgz", - "integrity": "sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.4.tgz", + "integrity": "sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg==", "requires": { - "browserslist": "^4.6.0", - "core-js-pure": "3.1.3", - "semver": "^6.1.0" + "browserslist": "^4.6.2", + "core-js-pure": "3.1.4", + "semver": "^6.1.1" }, "dependencies": { "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "core-js-pure": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.3.tgz", - "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==" + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.4.tgz", + "integrity": "sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==" }, "core-util-is": { "version": "1.0.2", @@ -3773,11 +3821,11 @@ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, "css-tree": { - "version": "1.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", - "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "version": "1.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", + "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", "requires": { - "mdn-data": "~1.1.0", + "mdn-data": "2.0.4", "source-map": "^0.5.3" } }, @@ -3786,11 +3834,6 @@ "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" }, - "css-url-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", - "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=" - }, "css-what": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", @@ -3893,18 +3936,23 @@ "mdn-data": "~1.1.0", "source-map": "^0.5.3" } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" } } }, "cssom": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==" + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "cssstyle": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", - "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "requires": { "cssom": "0.3.x" } @@ -4283,14 +4331,14 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.144", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.144.tgz", - "integrity": "sha512-jNRFJpfNrYm5uJ4x0q9oYMOfbL0JPOlkNli8GS/5zEmCjnE5jAtoCo4BYajHiqSPqEeAjtTdItL4p7EZw+jSfg==" + "version": "1.3.203", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.203.tgz", + "integrity": "sha512-Z1FjJKEBhYrCNmnususVk8khiBabVI/bSJB/295V4ghVt4MFmtbP+mXgRZLQZinEBI469U6FtiGgpXnlLs6qiQ==" }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -4465,18 +4513,18 @@ } }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "resolve-from": { "version": "4.0.0", @@ -4530,9 +4578,9 @@ } }, "eslint-module-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", - "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", "requires": { "debug": "^2.6.8", "pkg-dir": "^2.0.0" @@ -4767,9 +4815,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.0.tgz", - "integrity": "sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz", + "integrity": "sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA==" }, "eslint-scope": { "version": "4.0.3", @@ -4781,9 +4829,12 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", + "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", + "requires": { + "eslint-visitor-keys": "^1.0.0" + } }, "eslint-visitor-keys": { "version": "1.0.0", @@ -5022,9 +5073,9 @@ } }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -5129,9 +5180,9 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", "requires": { "websocket-driver": ">=0.5.1" } @@ -5253,9 +5304,9 @@ } }, "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" }, "flatten": { "version": "1.0.2", @@ -5523,9 +5574,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "growly": { "version": "1.3.0", @@ -5668,34 +5719,6 @@ "minimalistic-assert": "^1.0.1" } }, - "hast-util-from-parse5": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-5.0.1.tgz", - "integrity": "sha512-UfPzdl6fbxGAxqGYNThRUhRlDYY7sXu6XU9nQeX4fFZtV+IHbyEJtd+DUuwOqNV4z3K05E/1rIkoVr/JHmeWWA==", - "requires": { - "ccount": "^1.0.3", - "hastscript": "^5.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.1.2", - "xtend": "^4.0.1" - } - }, - "hast-util-parse-selector": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz", - "integrity": "sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw==" - }, - "hastscript": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.0.tgz", - "integrity": "sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ==", - "requires": { - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.2.0", - "property-information": "^5.0.1", - "space-separated-tokens": "^1.0.0" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -5834,12 +5857,19 @@ "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "http-proxy": { "version": "1.17.0", @@ -5970,11 +6000,6 @@ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5985,9 +6010,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -5995,9 +6020,9 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", @@ -6005,7 +6030,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -6220,11 +6245,6 @@ "path-is-inside": "^1.0.1" } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -6377,9 +6397,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "source-map": { "version": "0.6.1", @@ -6576,6 +6596,11 @@ "xml-name-validator": "^3.0.0" } }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, "whatwg-url": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", @@ -6614,9 +6639,9 @@ "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==" }, "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "version": "24.8.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.1.tgz", + "integrity": "sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g==", "requires": { "@jest/types": "^24.8.0", "anymatch": "^2.0.0", @@ -7505,11 +7530,6 @@ "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" } } }, @@ -7589,11 +7609,12 @@ } }, "jsx-ast-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", - "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", "requires": { - "array-includes": "^3.0.3" + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" } }, "killable": { @@ -7754,9 +7775,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -7779,20 +7800,20 @@ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=" }, "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "requires": { - "lodash._reinterpolate": "~3.0.0", + "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "requires": { - "lodash._reinterpolate": "~3.0.0" + "lodash._reinterpolate": "^3.0.0" } }, "lodash.unescape": { @@ -7806,9 +7827,9 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "loglevel": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.2.tgz", - "integrity": "sha512-Jt2MHrCNdtIe1W6co3tF5KXGRkzF+TYffiQstfXa04mrss9IKXzAAXYWak8LbZseAQY03sH2GzMCMU0ZOUc9bg==" + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", + "integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==" }, "loose-envify": { "version": "1.4.0", @@ -7897,9 +7918,9 @@ } }, "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, "media-typer": { "version": "0.3.0", @@ -8007,9 +8028,9 @@ } }, "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==" + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" }, "mime-db": { "version": "1.40.0", @@ -8080,9 +8101,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -8236,9 +8257,9 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "requires": { "assert": "^1.1.1", "browserify-zlib": "^0.2.0", @@ -8250,7 +8271,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -8262,7 +8283,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" }, "dependencies": { "punycode": { @@ -8297,9 +8318,9 @@ } }, "node-releases": { - "version": "1.1.22", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.22.tgz", - "integrity": "sha512-O6XpteBuntW1j86mw6LlovBIwTe+sO2+7vi9avQffNeIW4upgnaCVm6xrBWH+KATz7mNNRNNeEpuWB7dT6Cr3w==", + "version": "1.1.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.26.tgz", + "integrity": "sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ==", "requires": { "semver": "^5.3.0" }, @@ -8511,11 +8532,11 @@ } }, "openvidu-browser": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.10.0.tgz", - "integrity": "sha512-D+Eww0fh4omsNeeNSelj37s/mmvCe18MhtNsoaWXRSKclBWPrDpab6Ct4wonH5zpQK5sVCWG+KwEnDoBd1Y0Vg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.11.0.tgz", + "integrity": "sha512-dXnzHA9gf0Fhl88YijmPbFT/d7ERUHOMrqGObVeDc5NvG/7y2HCFafb/42O/mZ86IkBZnmqSrl6Q63aNlUZ2iA==", "requires": { - "@types/node": "12.0.3", + "@types/node": "12.6.8", "@types/platform": "1.3.2", "freeice": "2.2.2", "hark": "1.2.3", @@ -8525,93 +8546,38 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" - }, - "@types/fs-extra": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz", - "integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", - "requires": { - "handlebars": "*" - } - }, - "@types/highlight.js": { - "version": "9.12.3", - "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", - "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==" - }, - "@types/lodash": { - "version": "4.14.132", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.132.tgz", - "integrity": "sha512-RNUU1rrh85NgUJcjOOr96YXr+RHwInGbaQCZmlitqOaCKXffj8bh+Zxwuq5rjDy5OgzFldDVoqk4pyLEDiwxIw==" - }, - "@types/marked": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz", - "integrity": "sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==" - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.3.tgz", - "integrity": "sha512-zkOxCS/fA+3SsdA+9Yun0iANxzhQRiNwTvJSr6N95JhuJ/x27z9G2URx1Jpt3zYFfCGUXZGL5UDxt5eyLE7wgw==" + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==" }, "@types/platform": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.2.tgz", "integrity": "sha512-Tn6OuJDAG7bJbyi4R7HqcxXp1w2lmIxVXqyNhPt1Bm0FO2EWIi3CI87JVzF7ncqK0ZMPuUycS3wTMIk85EeF1Q==" }, - "@types/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==", - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -8627,9 +8593,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -8648,9 +8614,9 @@ } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, "amdefine": { "version": "1.0.1", @@ -8824,6 +8790,14 @@ "postcss": "~4.1.12" } }, + "backbone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", + "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", + "requires": { + "underscore": ">=1.8.3" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -8975,9 +8949,9 @@ } }, "browserify": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", - "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", + "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -9172,9 +9146,9 @@ } }, "caniuse-db": { - "version": "1.0.30000971", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000971.tgz", - "integrity": "sha512-ubSZfYXO2KMYtCVmDez82mjodeZa+mBYWAnBMAmFBPAn4C2PY4SD0eC/diYQD4Rj1K+WNdp0vr0JDtm0SQ6GNg==" + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000986.tgz", + "integrity": "sha512-8SKJ12AFwG0ReMjPwRH+keFsX/ucw2bi6LC7upeXBvxjgrMqHaTxgYhkRGm+eOwUWvVcqXDgqM7QNlRJMhvXZg==" }, "chalk": { "version": "2.4.2", @@ -9419,9 +9393,9 @@ }, "dependencies": { "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" } } }, @@ -9602,9 +9576,9 @@ } }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -9920,11 +9894,11 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -10503,9 +10477,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "grunt": { "version": "1.0.4", @@ -10759,11 +10733,11 @@ }, "dependencies": { "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } } } @@ -10827,11 +10801,11 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "chalk": { @@ -11041,9 +11015,9 @@ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=" }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "https-browserify": { "version": "1.0.0", @@ -11081,9 +11055,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -11293,6 +11267,11 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-base64": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", @@ -11403,9 +11382,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.memoize": { "version": "3.0.4", @@ -11426,6 +11405,11 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" }, + "lunr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.6.tgz", + "integrity": "sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -11453,9 +11437,9 @@ } }, "marked": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", - "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" }, "maxmin": { "version": "2.1.0", @@ -11593,9 +11577,9 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -12027,9 +12011,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -12143,6 +12127,11 @@ "util-deprecate": "~1.0.1" }, "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12213,9 +12202,9 @@ } }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } @@ -12257,9 +12246,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-json-parse": { "version": "1.0.1", @@ -12290,9 +12279,9 @@ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -12502,9 +12491,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -12588,6 +12577,13 @@ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -12687,9 +12683,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -12766,14 +12762,14 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", + "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -12781,7 +12777,7 @@ "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -12816,50 +12812,43 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.14.2.tgz", - "integrity": "sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ==", - "requires": { - "@types/fs-extra": "^5.0.3", - "@types/handlebars": "^4.0.38", - "@types/highlight.js": "^9.12.3", - "@types/lodash": "^4.14.110", - "@types/marked": "^0.4.0", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.15.0.tgz", + "integrity": "sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw==", + "requires": { "@types/minimatch": "3.0.3", - "@types/shelljs": "^0.8.0", - "fs-extra": "^7.0.0", - "handlebars": "^4.0.6", - "highlight.js": "^9.13.1", - "lodash": "^4.17.10", - "marked": "^0.4.0", + "fs-extra": "^8.1.0", + "handlebars": "^4.1.2", + "highlight.js": "^9.15.8", + "lodash": "^4.17.15", + "marked": "^0.7.0", "minimatch": "^3.0.0", - "progress": "^2.0.0", - "shelljs": "^0.8.2", - "typedoc-default-themes": "^0.5.0", - "typescript": "3.2.x" - }, - "dependencies": { - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==" - } + "progress": "^2.0.3", + "shelljs": "^0.8.3", + "typedoc-default-themes": "^0.6.0", + "typescript": "3.5.x" } }, "typedoc-default-themes": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz", - "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.6.0.tgz", + "integrity": "sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw==", + "requires": { + "backbone": "^1.4.0", + "jquery": "^3.4.1", + "lunr": "^2.3.6", + "underscore": "^1.9.1" + } }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==" + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==" }, "uglify-js": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", - "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" @@ -12894,6 +12883,11 @@ "xtend": "^4.0.1" } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -12904,35 +12898,14 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "universalify": { @@ -13018,6 +12991,13 @@ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "util-deprecate": { @@ -13053,11 +13033,12 @@ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -13075,9 +13056,9 @@ } }, "wildemitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.0.tgz", - "integrity": "sha1-Kd06ctaZw+J53QIcPNIVC4LJohE=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.1.tgz", + "integrity": "sha512-UMmSUoIQSir+XbBpTxOTS53uJ8s/lVhADCkEbhfRjUGFDPme/XGOb0sBWLx5sTz7Wx/2+TlAw1eK9O5lw5PiEw==" }, "wolfy87-eventemitter": { "version": "5.2.6", @@ -13109,9 +13090,9 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } }, @@ -13309,9 +13290,9 @@ } }, "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" }, "parseurl": { "version": "1.3.3", @@ -13324,9 +13305,9 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" }, "path-dirname": { "version": "1.0.2", @@ -13484,9 +13465,9 @@ } }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", + "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", "requires": { "async": "^1.5.2", "debug": "^2.2.0", @@ -13509,9 +13490,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", - "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", + "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -13672,11 +13653,11 @@ } }, "postcss-custom-properties": { - "version": "8.0.10", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.10.tgz", - "integrity": "sha512-GDL0dyd7++goDR4SSasYdRNNvp4Gqy1XMzcCnTijiph7VB27XXpJ8bW/AI0i2VSBZ55TpdGhMr37kMSpRfYD0Q==", + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", "requires": { - "postcss": "^7.0.14", + "postcss": "^7.0.17", "postcss-values-parser": "^2.0.1" } }, @@ -13832,11 +13813,11 @@ } }, "postcss-initial": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.0.tgz", - "integrity": "sha512-WzrqZ5nG9R9fUtrA+we92R4jhVvEB32IIRTzfIG/PLL8UV4CvbF1ugTEHEFX6vWxl41Xt5RTCJPEZkuWzrOM+Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.1.tgz", + "integrity": "sha512-I2Sz83ZSHybMNh02xQDK609lZ1/QOyYeuizCjzEhlMgeV/HcDJapQiH4yTqLjZss0X6/6VvKFXUeObaHpJoINw==", "requires": { - "lodash.template": "^4.2.4", + "lodash.template": "^4.5.0", "postcss": "^7.0.2" } }, @@ -13851,25 +13832,12 @@ } }, "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "requires": { - "cosmiconfig": "^4.0.0", + "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" - }, - "dependencies": { - "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" - } - } } }, "postcss-loader": { @@ -14028,9 +13996,9 @@ } }, "postcss-nesting": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.0.tgz", - "integrity": "sha512-WSsbVd5Ampi3Y0nk/SKr5+K34n52PqMqEfswu6RtU4r7wA8vSD+gM8/D9qq4aJkHImwn1+9iEFTbjoWsQeqtaQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", + "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", "requires": { "postcss": "^7.0.2" } @@ -14349,9 +14317,9 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "pretty-bytes": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.2.0.tgz", - "integrity": "sha512-ujANBhiUsl9AhREUDUEY1GPOharMGm8x8juS7qOHybcLi7XsKfrYQ88hSly1l2i0klXHTDYrlL8ihMCG55Dc3w==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", + "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" }, "pretty-error": { "version": "2.1.1", @@ -14391,9 +14359,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -14432,14 +14400,6 @@ "react-is": "^16.8.1" } }, - "property-information": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.1.0.tgz", - "integrity": "sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg==", - "requires": { - "xtend": "^4.0.1" - } - }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -14455,9 +14415,9 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==" }, "public-encrypt": { "version": "4.0.3", @@ -14602,6 +14562,13 @@ "raf": "3.4.1", "regenerator-runtime": "0.13.2", "whatwg-fetch": "3.0.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } } }, "react-dev-utils": { @@ -14636,6 +14603,14 @@ "text-table": "0.2.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -14833,14 +14808,14 @@ } }, "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" }, "regenerator-transform": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", - "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", "requires": { "private": "^0.1.6" } @@ -14855,9 +14830,9 @@ } }, "regexp-tree": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", - "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==" + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.11.tgz", + "integrity": "sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==" }, "regexpp": { "version": "2.0.1", @@ -14897,16 +14872,6 @@ } } }, - "rehype-parse": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-6.0.0.tgz", - "integrity": "sha512-V2OjMD0xcSt39G4uRdMTqDXXm6HwkUbLMDayYKA/d037j8/OtVSQ+tqKwYWOuyBeoCs/3clXRe30VUjeMDTBSA==", - "requires": { - "hast-util-from-parse5": "^5.0.0", - "parse5": "^5.0.0", - "xtend": "^4.0.1" - } - }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -14974,11 +14939,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" - }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -15045,11 +15005,6 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -15133,9 +15088,9 @@ } }, "rsvp": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", - "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==" + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" }, "run-async": { "version": "2.3.0", @@ -15262,11 +15217,11 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "saxes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz", - "integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", "requires": { - "xmlchars": "^1.3.1" + "xmlchars": "^2.1.1" } }, "scheduler": { @@ -15391,6 +15346,11 @@ "statuses": ">= 1.4.0 < 2" } }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -15415,9 +15375,9 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -15535,9 +15495,9 @@ } }, "sisteransi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz", + "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==" }, "slash": { "version": "2.0.0", @@ -15695,9 +15655,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -15744,11 +15704,6 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, - "space-separated-tokens": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz", - "integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==" - }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -15773,14 +15728,14 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "requires": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -15798,9 +15753,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -15826,9 +15781,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "readable-stream": { "version": "3.4.0", @@ -16060,17 +16015,21 @@ "has-flag": "^3.0.0" } }, + "svg-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.2.tgz", + "integrity": "sha512-1gtApepKFweigFZj3sGO8KT8LvVZK8io146EzXrpVuWCDAbISz/yMucco3hWTkpZNoPabM+dnMOpy6Swue68Zg==" + }, "svgo": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.2.2.tgz", - "integrity": "sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", + "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.28", - "css-url-regex": "^1.1.0", + "css-tree": "1.0.0-alpha.33", "csso": "^3.5.1", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", @@ -16082,17 +16041,17 @@ } }, "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "table": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz", - "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.4.tgz", + "integrity": "sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg==", "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", + "ajv": "^6.10.2", + "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, @@ -16297,25 +16256,20 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, - "trough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==" - }, "ts-pnp": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.2.tgz", "integrity": "sha512-f5Knjh7XCyRIzoC/z1Su1yLLRrPrFCgtUAh/9fCSP6NKbATwpOL1+idQVXQokK9GRFURn/jYPGPfegIctwunoA==" }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tsutils": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz", - "integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.1.tgz", + "integrity": "sha512-kiuZzD1uUA5DxGj/uxbde+ymp6VVdAxdzOIlAFbYKrPyla8/uiJ9JLBm1QsPhOm4Muj0/+cWEDP99yoCUcSl6Q==", "requires": { "tslib": "^1.8.1" } @@ -16405,64 +16359,15 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" }, - "unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", - "requires": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" - }, - "dependencies": { - "vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", - "requires": { - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - } - } - }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "uniq": { @@ -16484,18 +16389,13 @@ } }, "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "requires": { "imurmurhash": "^0.1.4" } }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -16616,6 +16516,13 @@ "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "util-deprecate": { @@ -16676,52 +16583,10 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.1.tgz", - "integrity": "sha512-lRHFCuC4SQBFr7Uq91oJDJxlnftoTLQ7eKIpMdubhYcVMho4781a8MWXLy3qZrZ0/STD1kRiKc0cQOHm4OkPeA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "dependencies": { - "unist-util-stringify-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz", - "integrity": "sha512-Zqlf6+FRI39Bah8Q6ZnNGrEHUhwJOkHde2MHVk96lLyftfJJckaPslKgzhVcviXj8KcE9UJM9F+a4JEiBUTYgA==", - "requires": { - "@types/unist": "^2.0.2" - } - }, - "vfile-message": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.1.tgz", - "integrity": "sha512-KtasSV+uVU7RWhUn4Lw+wW1Zl/nW8JWx7JCPps10Y9JRRIDeDXf8wfBLoOSsJLyo27DqMyAi54C6Jf/d6Kr2Bw==", - "requires": { - "@types/unist": "^2.0.2", - "unist-util-stringify-position": "^2.0.0" - } - } - } - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "w3c-hr-time": { "version": "1.0.1", @@ -16767,11 +16632,6 @@ "minimalistic-assert": "^1.0.0" } }, - "web-namespaces": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.3.tgz", - "integrity": "sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA==" - }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -16883,9 +16743,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "require-main-filename": { "version": "1.0.1", @@ -16978,11 +16838,12 @@ } }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -17287,20 +17148,15 @@ "async-limiter": "~1.0.0" } }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=" - }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xmlchars": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", - "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.1.1.tgz", + "integrity": "sha512-7hew1RPJ1iIuje/Y01bGD/mXokXxegAgVS+e+E0wSi2ILHQkYAH1+JXARwTjZSM4Z4Z+c73aKspEcqj+zPPL/w==" }, "xregexp": { "version": "4.0.0", @@ -17308,9 +17164,9 @@ "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "4.0.0", diff --git a/openvidu-insecure-react/package.json b/openvidu-insecure-react/package.json index 8b35ced80..6451c6ad4 100644 --- a/openvidu-insecure-react/package.json +++ b/openvidu-insecure-react/package.json @@ -1,10 +1,10 @@ { "name": "openvidu-insecure-react", - "version": "2.10.0", + "version": "2.11.0", "private": true, "dependencies": { "axios": "0.19.0", - "openvidu-browser": "2.10.0", + "openvidu-browser": "2.11.0", "react": "16.8.6", "react-dom": "16.8.6", "react-scripts": "3.0.0" diff --git a/openvidu-internet-explorer/web/index.html b/openvidu-internet-explorer/web/index.html index 4b457ff6e..16721c245 100644 --- a/openvidu-internet-explorer/web/index.html +++ b/openvidu-internet-explorer/web/index.html @@ -18,7 +18,7 @@ - + diff --git a/openvidu-internet-explorer/web/openvidu-browser-2.10.0.js b/openvidu-internet-explorer/web/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-internet-explorer/web/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-internet-explorer/web/openvidu-browser-2.11.0.js b/openvidu-internet-explorer/web/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-internet-explorer/web/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-ionic/package-lock.json b/openvidu-ionic/package-lock.json index f77e46902..38a16a466 100644 --- a/openvidu-ionic/package-lock.json +++ b/openvidu-ionic/package-lock.json @@ -1,6 +1,6 @@ { "name": "openvidu-ionic", - "version": "2.10.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -81,33 +81,6 @@ "worker-plugin": "3.1.0" }, "dependencies": { - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "core-js": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", - "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==", - "dev": true - }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, "rxjs": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", @@ -122,22 +95,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", "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 - }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, @@ -158,12 +115,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true - }, - "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", - "dev": true } } }, @@ -203,27 +154,6 @@ "source-map": "0.7.3" }, "dependencies": { - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "magic-string": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", - "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, "rxjs": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", @@ -288,12 +218,6 @@ "integrity": "sha512-3NkLpm6I6kEgC8J0I9EZ0fouXc/mm5J9zqJFCgA2jGqmsL0O64I7Uvi3AmUMnnRqc6u7uLgVVnY4pyBQ03nCiw==", "dev": true }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -303,33 +227,6 @@ "ms": "^2.1.1" } }, - "inquirer": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", - "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.11", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - } - }, - "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 - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -341,44 +238,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", "dev": true - }, - "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": { - "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" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } } } }, @@ -423,6 +282,51 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, "chokidar": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", @@ -443,3566 +347,3893 @@ "upath": "^1.1.1" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "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 - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "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 - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "is-extendable": "^0.1.0" } }, - "yargs": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz", - "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" } }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, + "optional": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "@angular/core": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.1.3.tgz", - "integrity": "sha512-45ocymDkXhmgluhaIX/O6IgqGPCLOlSYEXYpJ660QS1JgprKU7Ae9mWiNSmbBmT0OGV/sKKF8SNMQAGOHgio6Q==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/forms": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.1.3.tgz", - "integrity": "sha512-NabNiUsR1XgrI1/T8hFwbTH0BMqhKd1riSTU+xyJ3qVbdmORq1xnf6/dLbljNGxViMU28P8hBXvyf1BoTS+HyQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/http": { - "version": "7.2.15", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.15.tgz", - "integrity": "sha512-TR7PEdmLWNIre3Zn8lvyb4lSrvPUJhKLystLnp4hBMcWsJqq5iK8S3bnlR4viZ9HMlf7bW7+Hm4SI6aB3tdUtw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/language-service": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-8.1.3.tgz", - "integrity": "sha512-9s2LWlRlBhUXZ0oWh5ojYKnQgXgYH/VifEXteRWmEJ0dlwDApgw5Jk6usstDhv09XQvLdoumMQwOXf07zjcJrQ==", - "dev": true - }, - "@angular/platform-browser": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.1.3.tgz", - "integrity": "sha512-ihjoJd3OCmn/LBpYEDeCYnYJ1JRzeY6xYySNBEHNHLc07FX0TTiNwiZJHjbKoxdjr7qe6cj6gpT51M77pRlKKw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/platform-browser-dynamic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.1.3.tgz", - "integrity": "sha512-tsZWp8aFZNvbJ1TgP75GEfrwLe4SFW02kzEF12o7XlGU/iwnMjEs356rGHeueJZuWMFGS8PLL4mqPic7R5p53Q==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/router": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.1.3.tgz", - "integrity": "sha512-MOalKqqWcTaosHLNE5nmk5rsLRp3jE1PobGaFtbUJKTTZW0vS4rcr6iiRg2bZRv/srGixDXvNLenvYjTpzzTdw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", - "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", - "dev": true, - "requires": { - "@babel/types": "^7.5.5", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - } - } - }, - "@babel/parser": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", - "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", - "dev": true - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", - "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.5.5", - "@babel/types": "^7.5.5", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", - "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - } - } - }, - "@ionic-native/android-permissions": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@ionic-native/android-permissions/-/android-permissions-5.10.0.tgz", - "integrity": "sha512-8zzs+TfP0PUwnsGnZ+6quD3QPacq5ZxEF88ADjmNoE0btPSBjvAGCYrBNLhFshzsJ+VnDdCL01HTiK2qw7DAng==", - "requires": { - "@types/cordova": "^0.0.34" - } - }, - "@ionic-native/core": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@ionic-native/core/-/core-5.10.0.tgz", - "integrity": "sha512-HssaJBkXKVeQ5u0ejBmlzwsft5bwmtu2ZrsTVtK6jYiNm7Bez55II7c0cxcxs44l5wLu6uKuw/Ynt2vaZ2ngfg==", - "requires": { - "@types/cordova": "^0.0.34" - } - }, - "@ionic-native/splash-screen": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@ionic-native/splash-screen/-/splash-screen-5.10.0.tgz", - "integrity": "sha512-aAXEGRJUdtoIXQ/Mvb9KnIk5Y8KM731/Xg67PmYAf3FtOu0kiDmM2FrvRaYNUFGi1pmfhp3DJ/mcbHpGleTtBw==", - "requires": { - "@types/cordova": "^0.0.34" - } - }, - "@ionic-native/status-bar": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@ionic-native/status-bar/-/status-bar-5.10.0.tgz", - "integrity": "sha512-SrL2jFpDjbYkawxZc7xBO4MulhoLWSeXk0PSLPb2Hf2I4ru0pE76TBwtq59qgffXZ+oxmXUdIIrkNzKMMRiRZw==", - "requires": { - "@types/cordova": "^0.0.34" - } - }, - "@ionic/angular": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-4.7.0.tgz", - "integrity": "sha512-m4lMAm1wZb+oBAg4TBaI7DImDs8FLxG+z2dbqyRh1KGRbd1SExvyDq0Rleebl/AJBwiYHfCWltye1MEffUZBfA==", - "requires": { - "@ionic/core": "4.7.0", - "tslib": "^1.9.3" - } - }, - "@ionic/angular-toolkit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-2.0.0.tgz", - "integrity": "sha512-F0NVo/Wr3fVAsTjLn+IJMhEDpJ+Xqy6wjY1iJdKHTKY8ac2kWsGgA8ybN2ANaTcdeULmzUh1DgH35miQC55dsw==", - "dev": true, - "requires": { - "@schematics/angular": "^8.0.0", - "tslib": "^1.9.0", - "typescript": "3.4.3", - "ws": "^6.1.4" - }, - "dependencies": { - "typescript": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", - "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==", - "dev": true - } - } - }, - "@ionic/core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-4.7.0.tgz", - "integrity": "sha512-lE5Hsu07tzMYrnpznj4fcQPTFF5AilLzVr9K83wfiL7GDionWWMoBfyvgDAKM0ikS+mlmtyae0ENc2qQDzGRkA==", - "requires": { - "ionicons": "^4.6.2", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - } - } - }, - "@ionic/schematics-angular": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@ionic/schematics-angular/-/schematics-angular-1.0.7.tgz", - "integrity": "sha512-fWHTZ1uByPYXmKbiabnCe+c2bWYKFFKCW7xDcP8EZVC+lcy9tSJhsS8HOPBB3EvUcUO5LPmxoWFDoCs/1utBhQ==", - "dev": true, - "requires": { - "@schematics/angular": "0.9.0-beta.3", - "lodash": "^4.17.5", - "tslib": "^1.9.0", - "typescript": "3.0.1" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "0.9.0-beta.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.9.0-beta.3.tgz", - "integrity": "sha512-DKd4u3zzLxacgM/hrPB0dCk9aFL8UriH9u6suNHaLQnAft8hrLCZIvzetgTbufMKvU4jClgOtdeHTpt/0+fgaw==", - "dev": true, - "requires": { - "ajv": "6.5.3", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.2.2", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "0.9.0-beta.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.9.0-beta.3.tgz", - "integrity": "sha512-TC3OP/u1LQpngAU/g6DHmA8yoLbV6ml19x4cNjFeOhmADOvGV/e6fKni+rePORw+iIlOLvgmp0FhJd17uxT1Bw==", - "dev": true, - "requires": { - "@angular-devkit/core": "0.9.0-beta.3", - "rxjs": "6.2.2" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } } }, - "@schematics/angular": { - "version": "0.9.0-beta.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.9.0-beta.3.tgz", - "integrity": "sha512-4IRfPJqElpx+0/K1S4dlP7x0dO0DgT2/jpgsstrq710k2B3mCqbPUYk2gjvLl9ByJAQ4+PED4xoUmlHXAMbdTg==", - "dev": true, - "requires": { - "@angular-devkit/core": "0.9.0-beta.3", - "@angular-devkit/schematics": "0.9.0-beta.3", - "typescript": "3.0.1" - } + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, - "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "binary-extensions": "^1.0.0" } }, - "rxjs": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", - "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "tslib": "^1.9.0" + "kind-of": "^3.0.2" } }, - "typescript": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", - "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", - "dev": true - } - } - }, - "@ngtools/webpack": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.1.2.tgz", - "integrity": "sha512-xA1SZI6BiEqmfxyaxw2TobF3gkZdfyEeCP1zhPm38PjQ1zU7Xx3TbvxTeMKGV3EOTMxvUETDiS65YJrIvGnaNA==", - "dev": true, - "requires": { - "@angular-devkit/core": "8.1.2", - "enhanced-resolve": "4.1.0", - "rxjs": "6.4.0", - "tree-kill": "1.2.1", - "webpack-sources": "1.3.0" - }, - "dependencies": { - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@schematics/angular": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-8.1.2.tgz", - "integrity": "sha512-BeEzuS0s4j+BPboUhl97VMfhj7V+HpNbbY3PkD3TLd0cnSEoaLmtX+YjxbxZgwk6vhDp+l6YtpWt//5H/+0rFQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "8.1.2", - "@angular-devkit/schematics": "8.1.2" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.1.2.tgz", - "integrity": "sha512-sNkqXbkHE9+ObtLOYmDKJL1bOf1zY0AwGVKemgDqCmu1mRUNqhb7CmF13DRscfU3MEcuiJYDjXqBQDjIszrFiw==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "ajv": "6.10.0", - "fast-json-stable-stringify": "2.0.0", - "magic-string": "0.25.3", - "rxjs": "6.4.0", - "source-map": "0.7.3" + "is-buffer": "^1.1.5" } }, - "@angular-devkit/schematics": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-8.1.2.tgz", - "integrity": "sha512-Di/3vPR4jwdYcMAk13t19sAF0qQUH8KSkFcmO/5E/gECTL1tXNvV690K1Vhn6zpeE17Z1MLB5HwRNcb6nJkD+Q==", + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "@angular-devkit/core": "8.1.2", - "rxjs": "6.4.0" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, - "magic-string": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", - "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } + "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 }, - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "tslib": "^1.9.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } - } - } - }, - "@schematics/update": { - "version": "0.801.2", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.801.2.tgz", - "integrity": "sha512-xb54QXvII1JLdqgEqsh6mWu5qTt5UezmOWTZayRegsj0vNlzWFzoLXpiPFCWVEKUODa6aV4O5XW5CiQuVYPVuQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "8.1.2", - "@angular-devkit/schematics": "8.1.2", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "pacote": "9.5.1", - "rxjs": "6.4.0", - "semver": "6.2.0", - "semver-intersect": "1.4.0" - }, - "dependencies": { - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "tslib": "^1.9.0" + "ansi-regex": "^4.1.0" } }, - "semver": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", - "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", - "dev": true - } - } - }, - "@types/cordova": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", - "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/jasmine": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.15.tgz", - "integrity": "sha512-MljubxUVLT9wh/0NiyRWlcxSu/0axK+UYheZ04N5yaQclQkE8JuFYMsmwltPap2LEsJrvSf5p49/1514IY+d1Q==", - "dev": true - }, - "@types/jasminewd2": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.6.tgz", - "integrity": "sha512-2ZOKrxb8bKRmP/po5ObYnRDgFE4i+lQiEB27bAMmtMWLgJSqlIDqlLx6S0IRorpOmOPRQ6O80NujTmQAtBkeNw==", - "dev": true, - "requires": { - "@types/jasmine": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "12.6.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", - "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", - "dev": true - }, - "@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", - "dev": true - }, - "@types/selenium-webdriver": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz", - "integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/webpack-sources": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz", - "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - }, - "dependencies": { - "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 + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "yargs": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz", + "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, + "@angular/core": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.1.3.tgz", + "integrity": "sha512-45ocymDkXhmgluhaIX/O6IgqGPCLOlSYEXYpJ660QS1JgprKU7Ae9mWiNSmbBmT0OGV/sKKF8SNMQAGOHgio6Q==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" + "tslib": "^1.9.0" } }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, + "@angular/forms": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.1.3.tgz", + "integrity": "sha512-NabNiUsR1XgrI1/T8hFwbTH0BMqhKd1riSTU+xyJ3qVbdmORq1xnf6/dLbljNGxViMU28P8hBXvyf1BoTS+HyQ==", "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "tslib": "^1.9.0" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "@angular/http": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.15.tgz", + "integrity": "sha512-TR7PEdmLWNIre3Zn8lvyb4lSrvPUJhKLystLnp4hBMcWsJqq5iK8S3bnlR4viZ9HMlf7bW7+Hm4SI6aB3tdUtw==", "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "tslib": "^1.9.0" } }, - "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "@angular/language-service": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-8.1.3.tgz", + "integrity": "sha512-9s2LWlRlBhUXZ0oWh5ojYKnQgXgYH/VifEXteRWmEJ0dlwDApgw5Jk6usstDhv09XQvLdoumMQwOXf07zjcJrQ==", "dev": true }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true + "@angular/platform-browser": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.1.3.tgz", + "integrity": "sha512-ihjoJd3OCmn/LBpYEDeCYnYJ1JRzeY6xYySNBEHNHLc07FX0TTiNwiZJHjbKoxdjr7qe6cj6gpT51M77pRlKKw==", + "requires": { + "tslib": "^1.9.0" + } }, - "adm-zip": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", - "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", - "dev": true + "@angular/platform-browser-dynamic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.1.3.tgz", + "integrity": "sha512-tsZWp8aFZNvbJ1TgP75GEfrwLe4SFW02kzEF12o7XlGU/iwnMjEs356rGHeueJZuWMFGS8PLL4mqPic7R5p53Q==", + "requires": { + "tslib": "^1.9.0" + } }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true + "@angular/router": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.1.3.tgz", + "integrity": "sha512-MOalKqqWcTaosHLNE5nmk5rsLRp3jE1PobGaFtbUJKTTZW0vS4rcr6iiRg2bZRv/srGixDXvNLenvYjTpzzTdw==", + "requires": { + "tslib": "^1.9.0" + } }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "@babel/highlight": "^7.0.0" } }, - "agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", "dev": true, "requires": { - "humanize-ms": "^1.2.1" + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "ajv": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", - "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "android-versions": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.4.0.tgz", - "integrity": "sha512-GnomfYsBq+nZh3c3UH/4r9Jt6FuTxdhUJbeHIdYOH5xBhQ8I0ZzC2/RM5IFFIjrzuNWSHb8JWP1lPK0/a26jrg==", + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, "requires": { - "semver": "^5.4.1" + "@babel/types": "^7.0.0" } }, - "ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", "dev": true }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } }, - "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==", + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "dev": true, "requires": { - "color-convert": "^1.9.0" + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@ionic-native/android-permissions": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@ionic-native/android-permissions/-/android-permissions-5.10.0.tgz", + "integrity": "sha512-8zzs+TfP0PUwnsGnZ+6quD3QPacq5ZxEF88ADjmNoE0btPSBjvAGCYrBNLhFshzsJ+VnDdCL01HTiK2qw7DAng==", + "requires": { + "@types/cordova": "^0.0.34" } }, - "app-root-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", - "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", - "dev": true - }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, + "@ionic-native/core": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@ionic-native/core/-/core-5.10.0.tgz", + "integrity": "sha512-HssaJBkXKVeQ5u0ejBmlzwsft5bwmtu2ZrsTVtK6jYiNm7Bez55II7c0cxcxs44l5wLu6uKuw/Ynt2vaZ2ngfg==", "requires": { - "default-require-extensions": "^2.0.0" + "@types/cordova": "^0.0.34" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arg": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", - "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, + "@ionic-native/splash-screen": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@ionic-native/splash-screen/-/splash-screen-5.10.0.tgz", + "integrity": "sha512-aAXEGRJUdtoIXQ/Mvb9KnIk5Y8KM731/Xg67PmYAf3FtOu0kiDmM2FrvRaYNUFGi1pmfhp3DJ/mcbHpGleTtBw==", "requires": { - "sprintf-js": "~1.0.2" + "@types/cordova": "^0.0.34" } }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, + "@ionic-native/status-bar": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@ionic-native/status-bar/-/status-bar-5.10.0.tgz", + "integrity": "sha512-SrL2jFpDjbYkawxZc7xBO4MulhoLWSeXk0PSLPb2Hf2I4ru0pE76TBwtq59qgffXZ+oxmXUdIIrkNzKMMRiRZw==", "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" + "@types/cordova": "^0.0.34" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, + "@ionic/angular": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-4.7.0.tgz", + "integrity": "sha512-m4lMAm1wZb+oBAg4TBaI7DImDs8FLxG+z2dbqyRh1KGRbd1SExvyDq0Rleebl/AJBwiYHfCWltye1MEffUZBfA==", "requires": { - "array-uniq": "^1.0.1" + "@ionic/core": "4.7.0", + "tslib": "^1.9.3" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "@ionic/angular-toolkit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-2.0.0.tgz", + "integrity": "sha512-F0NVo/Wr3fVAsTjLn+IJMhEDpJ+Xqy6wjY1iJdKHTKY8ac2kWsGgA8ybN2ANaTcdeULmzUh1DgH35miQC55dsw==", "dev": true, "requires": { - "safer-buffer": "~2.1.0" + "@schematics/angular": "^8.0.0", + "tslib": "^1.9.0", + "typescript": "3.4.3", + "ws": "^6.1.4" + }, + "dependencies": { + "typescript": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", + "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==", + "dev": true + } } }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, + "@ionic/core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-4.7.0.tgz", + "integrity": "sha512-lE5Hsu07tzMYrnpznj4fcQPTFF5AilLzVr9K83wfiL7GDionWWMoBfyvgDAKM0ikS+mlmtyae0ENc2qQDzGRkA==", "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "ionicons": "^4.6.2", + "tslib": "^1.10.0" } }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "@ionic/schematics-angular": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@ionic/schematics-angular/-/schematics-angular-1.0.7.tgz", + "integrity": "sha512-fWHTZ1uByPYXmKbiabnCe+c2bWYKFFKCW7xDcP8EZVC+lcy9tSJhsS8HOPBB3EvUcUO5LPmxoWFDoCs/1utBhQ==", "dev": true, "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" + "@schematics/angular": "0.9.0-beta.3", + "lodash": "^4.17.5", + "tslib": "^1.9.0", + "typescript": "3.0.1" }, "dependencies": { - "inherits": { + "@angular-devkit/core": { + "version": "0.9.0-beta.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.9.0-beta.3.tgz", + "integrity": "sha512-DKd4u3zzLxacgM/hrPB0dCk9aFL8UriH9u6suNHaLQnAft8hrLCZIvzetgTbufMKvU4jClgOtdeHTpt/0+fgaw==", + "dev": true, + "requires": { + "ajv": "6.5.3", + "chokidar": "2.0.4", + "fast-json-stable-stringify": "2.0.0", + "rxjs": "6.2.2", + "source-map": "0.7.3" + } + }, + "@angular-devkit/schematics": { + "version": "0.9.0-beta.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.9.0-beta.3.tgz", + "integrity": "sha512-TC3OP/u1LQpngAU/g6DHmA8yoLbV6ml19x4cNjFeOhmADOvGV/e6fKni+rePORw+iIlOLvgmp0FhJd17uxT1Bw==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.9.0-beta.3", + "rxjs": "6.2.2" + } + }, + "@schematics/angular": { + "version": "0.9.0-beta.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.9.0-beta.3.tgz", + "integrity": "sha512-4IRfPJqElpx+0/K1S4dlP7x0dO0DgT2/jpgsstrq710k2B3mCqbPUYk2gjvLl9ByJAQ4+PED4xoUmlHXAMbdTg==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.9.0-beta.3", + "@angular-devkit/schematics": "0.9.0-beta.3", + "typescript": "3.0.1" + } + }, + "ajv": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", + "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "inherits": "2.0.1" + "binary-extensions": "^1.0.0" } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "autoprefixer": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz", - "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==", - "dev": true, - "requires": { - "browserslist": "^4.6.1", - "caniuse-lite": "^1.0.30000971", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.16", - "postcss-value-parser": "^3.3.1" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "readdirp": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "rxjs": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", + "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "tslib": "^1.9.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "typescript": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", + "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", "dev": true } } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "@ngtools/webpack": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.1.2.tgz", + "integrity": "sha512-xA1SZI6BiEqmfxyaxw2TobF3gkZdfyEeCP1zhPm38PjQ1zU7Xx3TbvxTeMKGV3EOTMxvUETDiS65YJrIvGnaNA==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "@angular-devkit/core": "8.1.2", + "enhanced-resolve": "4.1.0", + "rxjs": "6.4.0", + "tree-kill": "1.2.1", + "webpack-sources": "1.3.0" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } } } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "@schematics/angular": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-8.1.2.tgz", + "integrity": "sha512-BeEzuS0s4j+BPboUhl97VMfhj7V+HpNbbY3PkD3TLd0cnSEoaLmtX+YjxbxZgwk6vhDp+l6YtpWt//5H/+0rFQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@angular-devkit/core": "8.1.2", + "@angular-devkit/schematics": "8.1.2" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "@schematics/update": { + "version": "0.801.2", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.801.2.tgz", + "integrity": "sha512-xb54QXvII1JLdqgEqsh6mWu5qTt5UezmOWTZayRegsj0vNlzWFzoLXpiPFCWVEKUODa6aV4O5XW5CiQuVYPVuQ==", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "@angular-devkit/core": "8.1.2", + "@angular-devkit/schematics": "8.1.2", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "pacote": "9.5.1", + "rxjs": "6.4.0", + "semver": "6.2.0", + "semver-intersect": "1.4.0" }, "dependencies": { - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", + "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", "dev": true } } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "@types/jasmine": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.15.tgz", + "integrity": "sha512-MljubxUVLT9wh/0NiyRWlcxSu/0axK+UYheZ04N5yaQclQkE8JuFYMsmwltPap2LEsJrvSf5p49/1514IY+d1Q==", + "dev": true + }, + "@types/jasminewd2": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.6.tgz", + "integrity": "sha512-2ZOKrxb8bKRmP/po5ObYnRDgFE4i+lQiEB27bAMmtMWLgJSqlIDqlLx6S0IRorpOmOPRQ6O80NujTmQAtBkeNw==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "@types/jasmine": "*" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "@types/node": { + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", "dev": true }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "@types/selenium-webdriver": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz", + "integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==", + "dev": true + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/webpack-sources": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz", + "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.6.1" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "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 } } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", "dev": true }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", "dev": true, "requires": { - "tweetnacl": "^0.14.3" + "@webassemblyjs/wast-printer": "1.8.5" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", "dev": true, "requires": { - "callsite": "1.0.0" + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" } }, - "big-integer": { - "version": "1.6.43", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.43.tgz", - "integrity": "sha512-9dULc9jsKmXl0Aeunug8wbF+58n+hQoFjqClN7WeZwGLh0XJUWyJJ9Ee+Ep+Ql/J9fRsTVaeThp8MhiCCrY0Jg==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", "dev": true }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } }, - "blocking-proxy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", - "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", "dev": true, "requires": { - "minimist": "^1.2.0" + "@xtuc/long": "4.2.2" } }, - "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", "dev": true }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "dev": true, "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - } + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", "dev": true, "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - }, - "dependencies": { - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - } + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" } }, - "bplist-creator": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", - "integrity": "sha1-N98VNgkoJLh8QvlXsBNEEXNyrkU=", + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "dev": true, "requires": { - "stream-buffers": "~2.2.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "bplist-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", - "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "dev": true, "requires": { - "big-integer": "^1.6.7" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "acorn": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "adm-zip": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "es6-promisify": "^5.0.0" } }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "humanize-ms": "^1.2.1" } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "android-versions": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.4.0.tgz", + "integrity": "sha512-GnomfYsBq+nZh3c3UH/4r9Jt6FuTxdhUJbeHIdYOH5xBhQ8I0ZzC2/RM5IFFIjrzuNWSHb8JWP1lPK0/a26jrg==", "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "semver": "^5.4.1" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "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==", "requires": { - "pako": "~1.0.5" + "color-convert": "^1.9.0" } }, - "browserslist": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.3.tgz", - "integrity": "sha512-CNBqTCq22RKM8wKJNowcqihHJ4SkI8CGeK7KOR9tPboXUuS5Zk5lQgzzTbs4oxD8x+6HUshZUa2OyNI9lR93bQ==", + "anymatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.0.3.tgz", + "integrity": "sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000975", - "electron-to-chromium": "^1.3.164", - "node-releases": "^1.1.23" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "browserstack": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz", - "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==", + "app-root-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", + "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { - "https-proxy-agent": "^2.2.1" + "default-require-extensions": "^2.0.0" } }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "sprintf-js": "~1.0.2" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", "dev": true, "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" } }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "buffer-indexof": { + "array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } }, - "buffer-xor": { + "array-uniq": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true - } - } + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "safer-buffer": "~2.1.0" } }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "callsites": "^2.0.0" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "requires": { - "caller-callsite": "^2.0.0" + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "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" + } + } } }, - "callsite": { + "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", "dev": true }, - "caniuse-lite": { - "version": "1.0.30000979", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz", - "integrity": "sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw==", + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, - "canonical-path": { + "async-limiter": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "autoprefixer": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz", + "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "browserslist": "^4.6.1", + "caniuse-lite": "^1.0.30000971", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.16", + "postcss-value-parser": "^3.3.1" } }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-dependency-plugin": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz", - "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==", + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "source-map": "~0.6.0" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" }, "dependencies": { "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "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=", + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "babel-runtime": "^6.22.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 - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.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 - }, - "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=", + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", "dev": true - }, - "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" - } - }, - "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" - } } } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } }, - "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "for-own": "^1.0.0", - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", "dev": true }, - "codelyzer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.1.0.tgz", - "integrity": "sha512-QiyY2/oDQnYx4mAVEDqr+z9MwrOto18tQFjExiuRChXCy0yvngS5fQpWIxvAGpbOmZFiR1PRTRLbEI71u10maA==", + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "app-root-path": "^2.2.1", - "aria-query": "^3.0.0", - "axobject-query": "^2.0.2", - "css-selector-tokenizer": "^0.7.1", - "cssauron": "^1.4.0", - "damerau-levenshtein": "^1.0.4", - "semver-dsl": "^1.0.1", - "source-map": "^0.5.7", - "sprintf-js": "^1.1.2" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } } }, - "collection-visit": { + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "base64id": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "tweetnacl": "^0.14.3" } }, - "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==", + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, "requires": { - "color-name": "1.1.3" + "callsite": "1.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "big-integer": { + "version": "1.6.44", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz", + "integrity": "sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ==" }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, - "compare-versions": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.0.tgz", - "integrity": "sha512-hX+4kt2Rcwu+x1U0SsEFCn1quURjEjPEGH/cPBlpME/IidGimAdwfMU+B+xDr7et/KTR7VH2+ZqWGerv4NGs2w==", - "dev": true + "blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", "dev": true }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + } + } }, - "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, "requires": { - "mime-db": ">= 1.40.0 < 2" + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + } } }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "bplist-creator": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", + "integrity": "sha1-N98VNgkoJLh8QvlXsBNEEXNyrkU=", "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" + "stream-buffers": "~2.2.0" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "bplist-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", + "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", + "requires": { + "big-integer": "^1.6.7" + } }, - "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, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" + "fill-range": "^7.0.1" } }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "date-now": "^0.1.4" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, "requires": { - "safe-buffer": "5.1.2" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "safe-buffer": "~5.1.1" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q==", + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "cacache": "^11.3.2", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - } + "pako": "~1.0.5" } }, - "cordova-android": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-8.0.0.tgz", - "integrity": "sha512-Ipv8HbVJpxEyYFSFLTEOaLRp0yxBtJVNbgSuDEB4naa34FzQaRWSNiiMcPJnO+x3hRXNt7pcwa46hARNzhn7+w==", + "browserslist": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.3.tgz", + "integrity": "sha512-CNBqTCq22RKM8wKJNowcqihHJ4SkI8CGeK7KOR9tPboXUuS5Zk5lQgzzTbs4oxD8x+6HUshZUa2OyNI9lR93bQ==", + "dev": true, "requires": { - "android-versions": "^1.3.0", - "cordova-common": "^3.1.0", - "elementtree": "^0.1.7", - "nopt": "^4.0.1", - "properties-parser": "^0.3.1", - "q": "^1.4.1", - "shelljs": "^0.5.3" + "caniuse-lite": "^1.0.30000975", + "electron-to-chromium": "^1.3.164", + "node-releases": "^1.1.23" } }, - "cordova-browser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cordova-browser/-/cordova-browser-6.0.0.tgz", - "integrity": "sha512-G61S7fhnVVJC98lvkGeKCVpfFtoW0a1P1Sg9TK+n03g3yupDMIM7XuecWuJ3KEMRhED4+CEc2hauruAff7oXrw==", + "browserstack": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz", + "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==", + "dev": true, "requires": { - "cordova-common": "^3.1.0", - "cordova-serve": "^3.0.0", - "nopt": "^4.0.1", - "shelljs": "^0.5.3" + "https-proxy-agent": "^2.2.1" } }, - "cordova-common": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cordova-common/-/cordova-common-3.1.0.tgz", - "integrity": "sha512-J2MM1ioyLlBYdwdXH40OZL4hN7XEBOfurddKYifF4aTkb2PkbeM+KVORt53eyU+8ScA0QmRLuTG0EM55eLms0A==", + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, "requires": { - "ansi": "^0.3.1", - "bplist-parser": "^0.1.0", - "cross-spawn": "^6.0.5", - "elementtree": "0.1.7", - "endent": "^1.1.1", - "fs-extra": "^7.0.0", - "glob": "^7.1.2", - "minimatch": "^3.0.0", - "plist": "^3.0.1", - "q": "^1.4.1", - "strip-bom": "^3.0.0", - "underscore": "^1.8.3", - "which": "^1.3.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, - "cordova-ios": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/cordova-ios/-/cordova-ios-5.0.1.tgz", - "integrity": "sha512-JcFyDmlyzY2OQJo0eHpuFERFqvO4daHl8HL96RhUVjJVtuoqXHsOF0xTuQSAqIbefelMPEWwY3Lc/dvT4ttTwQ==", + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, "requires": { - "cordova-common": "^3.1.0", - "ios-sim": "^8.0.1", - "nopt": "^4.0.1", - "plist": "^3.0.1", - "q": "^1.5.1", - "shelljs": "^0.5.3", - "unorm": "^1.4.1", - "xcode": "^2.0.0", - "xml-escape": "^1.1.0" - }, - "dependencies": { - "xcode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.0.0.tgz", - "integrity": "sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw==", - "requires": { - "simple-plist": "^1.0.0", - "uuid": "^3.3.2" - } - } + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, - "cordova-plugin-android-permissions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cordova-plugin-android-permissions/-/cordova-plugin-android-permissions-1.0.0.tgz", - "integrity": "sha1-nnwRa+Zo6336QUkbE9jUfalUgUk=" - }, - "cordova-plugin-device": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/cordova-plugin-device/-/cordova-plugin-device-2.0.3.tgz", - "integrity": "sha512-Jb3V72btxf3XHpkPQsGdyc8N6tVBYn1vsxSFj43fIz9vonJDUThYPCJJHqk6PX6N4dJw6I4FjxkpfCR4LDYMlw==" - }, - "cordova-plugin-ionic-keyboard": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-keyboard/-/cordova-plugin-ionic-keyboard-2.1.3.tgz", - "integrity": "sha512-6ucQ6FdlLdBm8kJfFnzozmBTjru/0xekHP/dAhjoCZggkGRlgs8TsUJFkxa/bV+qi7Dlo50JjmpE4UMWAO+aOQ==" + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true }, - "cordova-plugin-ionic-webview": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-webview/-/cordova-plugin-ionic-webview-4.1.1.tgz", - "integrity": "sha512-y8drBhMdkHKUr0zu+UGkFGsDrkCsxjbCd3RzzlyDxcEzdHWvasRM5gyDiKBHkziT2iHYzEAjXwkT1ZXKU3OY9Q==" + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true }, - "cordova-plugin-iosrtc": { - "version": "git+https://github.com/OpenVidu/cordova-plugin-iosrtc.git#b458a666b5a1879460585168fc2242e9fd38a584", - "from": "git+https://github.com/OpenVidu/cordova-plugin-iosrtc.git", - "requires": { - "debug": "^2.6.8", - "domready": "^1.0.8", - "random-number": "^0.0.7", - "yaeti": "^0.0.6" - } + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, - "cordova-plugin-splashscreen": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-5.0.3.tgz", - "integrity": "sha512-rnoDXMDfzoeHDBvsnu6JmzDE/pV5YJCAfc5hYX/Mb2BIXGgSjFJheByt0tU6kp3Wl40tSyFX4pYfBwFblBGyRg==" + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true }, - "cordova-plugin-statusbar": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/cordova-plugin-statusbar/-/cordova-plugin-statusbar-2.4.3.tgz", - "integrity": "sha512-ThmXzl6QIKWFXf4wWw7Q/zpB+VKkz3VM958+5A0sXD4jmR++u7KnGttLksXshVwWr6lvGwUebLYtIyXwS4Ovcg==" + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true }, - "cordova-plugin-whitelist": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/cordova-plugin-whitelist/-/cordova-plugin-whitelist-1.3.4.tgz", - "integrity": "sha512-EYC5eQFVkoYXq39l7tYKE6lEjHJ04mvTmKXxGL7quHLdFPfJMNzru/UYpn92AOfpl3PQaZmou78C7EgmFOwFQQ==" + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true }, - "cordova-serve": { + "builtin-status-codes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cordova-serve/-/cordova-serve-3.0.0.tgz", - "integrity": "sha512-h479g/5a0PXn//yiFuMrD5MDEbB+mtihNkWcE6uD/aCh/6z0FRZ9sWH3NfZbHDB+Bp1yGLYsjbH8LZBL8KOQ0w==", - "requires": { - "chalk": "^2.4.1", - "compression": "^1.6.0", - "express": "^4.13.3", - "opn": "^5.3.0", - "which": "^1.3.0" - } - }, - "core-js": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", - "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", "dev": true }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "cacache": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "callsites": "^2.0.0" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "caller-callsite": "^2.0.0" } }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, - "css-selector-tokenizer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", - "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", - "dev": true, - "requires": { - "cssesc": "^0.1.0", - "fastparse": "^1.1.1", - "regexpu-core": "^1.0.0" - } - }, - "cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", - "dev": true, - "requires": { - "through": "X.X.X" - } + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true }, - "cssesc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "caniuse-lite": { + "version": "1.0.30000979", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz", + "integrity": "sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw==", "dev": true }, - "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "canonical-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, - "damerau-levenshtein": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", - "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "assert-plus": "^1.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "date-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", - "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "chokidar": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", + "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", + "dev": true, + "requires": { + "anymatch": "^3.0.1", + "braces": "^3.0.2", + "fsevents": "^2.0.6", + "glob-parent": "^5.0.0", + "is-binary-path": "^2.1.0", + "is-glob": "^4.0.1", + "normalize-path": "^3.0.0", + "readdirp": "^3.1.1" + }, + "dependencies": { + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chownr": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, "requires": { - "ms": "2.0.0" + "tslib": "^1.9.0" } }, - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "circular-dependency-plugin": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz", + "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==", "dev": true }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } } }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", "dev": true, "requires": { - "strip-bom": "^3.0.0" + "source-map": "~0.6.0" + }, + "dependencies": { + "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 + } } }, - "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==", + "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": { - "object-keys": "^1.0.12" + "restore-cursor": "^2.0.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "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 + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "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": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "ansi-regex": "^3.0.0" } } } }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "clone-deep": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", + "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", "dev": true, "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" + "for-own": "^1.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.0", + "shallow-clone": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "codelyzer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.1.0.tgz", + "integrity": "sha512-QiyY2/oDQnYx4mAVEDqr+z9MwrOto18tQFjExiuRChXCy0yvngS5fQpWIxvAGpbOmZFiR1PRTRLbEI71u10maA==", + "dev": true, + "requires": { + "app-root-path": "^2.2.1", + "aria-query": "^3.0.0", + "axobject-query": "^2.0.2", + "css-selector-tokenizer": "^0.7.1", + "cssauron": "^1.4.0", + "damerau-levenshtein": "^1.0.4", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.7", + "sprintf-js": "^1.1.2" }, "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true } } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "dependency-graph": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", - "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", - "dev": true - }, - "des.js": { + "collection-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "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==", "requires": { - "repeating": "^2.0.0" + "color-name": "1.1.3" } }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, - "dezalgo": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { - "asap": "^2.0.0", - "wrappy": "1" + "delayed-stream": "~1.0.0" } }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, + "compare-versions": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.0.tgz", + "integrity": "sha512-hX+4kt2Rcwu+x1U0SsEFCn1quURjEjPEGH/cPBlpME/IidGimAdwfMU+B+xDr7et/KTR7VH2+ZqWGerv4NGs2w==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "mime-db": ">= 1.40.0 < 2" } }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "requires": { - "path-type": "^3.0.0" + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" } }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "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": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "dev": true, "requires": { - "buffer-indexof": "^1.0.0" + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "date-now": "^0.1.4" } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, - "domready": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", - "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "safe-buffer": "5.1.2" } }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "safe-buffer": "~5.1.1" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.3.200", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz", - "integrity": "sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg==", - "dev": true + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, - "elementtree": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", - "integrity": "sha1-mskb5uUvtuYkTE5UpKw+2K6OKcA=", - "requires": { - "sax": "1.1.4" - } + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "elliptic": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", - "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^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 - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "copy-webpack-plugin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q==", "dev": true, "requires": { - "iconv-lite": "~0.4.13" + "cacache": "^11.3.2", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "webpack-log": "^2.0.0" } }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, + "cordova-android": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-8.0.0.tgz", + "integrity": "sha512-Ipv8HbVJpxEyYFSFLTEOaLRp0yxBtJVNbgSuDEB4naa34FzQaRWSNiiMcPJnO+x3hRXNt7pcwa46hARNzhn7+w==", "requires": { - "once": "^1.4.0" + "android-versions": "^1.3.0", + "cordova-common": "^3.1.0", + "elementtree": "^0.1.7", + "nopt": "^4.0.1", + "properties-parser": "^0.3.1", + "q": "^1.4.1", + "shelljs": "^0.5.3" } }, - "endent": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/endent/-/endent-1.3.0.tgz", - "integrity": "sha512-C8AryqPPwtydqcpO5AF6k9Bd1EpFkQtvsefJqS3y3n8TG13Jy63MascDxTOULZYqrUde+dK6BjNc6LIMr3iI2A==", + "cordova-browser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cordova-browser/-/cordova-browser-6.0.0.tgz", + "integrity": "sha512-G61S7fhnVVJC98lvkGeKCVpfFtoW0a1P1Sg9TK+n03g3yupDMIM7XuecWuJ3KEMRhED4+CEc2hauruAff7oXrw==", "requires": { - "dedent": "^0.7.0", - "fast-json-parse": "^1.0.3", - "objectorarray": "^1.0.3" + "cordova-common": "^3.1.0", + "cordova-serve": "^3.0.0", + "nopt": "^4.0.1", + "shelljs": "^0.5.3" } }, - "engine.io": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", - "dev": true, + "cordova-common": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cordova-common/-/cordova-common-3.2.0.tgz", + "integrity": "sha512-EvlQ6PirfR65hGDoQvsluW00uSS2MTVIRKQ3c1Xvsddx7D5T5JgF3fHWkGik/Y/8yNcpI0zI2NcJyie2z/ak2A==", "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } + "ansi": "^0.3.1", + "bplist-parser": "^0.1.0", + "cross-spawn": "^6.0.5", + "elementtree": "0.1.7", + "endent": "^1.1.1", + "fs-extra": "^8.0.0", + "glob": "^7.1.2", + "minimatch": "^3.0.0", + "plist": "^3.0.1", + "q": "^1.4.1", + "strip-bom": "^3.0.0", + "underscore": "^1.8.3", + "which": "^1.3.0" } }, - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", - "dev": true, + "cordova-ios": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/cordova-ios/-/cordova-ios-5.0.1.tgz", + "integrity": "sha512-JcFyDmlyzY2OQJo0eHpuFERFqvO4daHl8HL96RhUVjJVtuoqXHsOF0xTuQSAqIbefelMPEWwY3Lc/dvT4ttTwQ==", "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } + "cordova-common": "^3.1.0", + "ios-sim": "^8.0.1", + "nopt": "^4.0.1", + "plist": "^3.0.1", + "q": "^1.5.1", + "shelljs": "^0.5.3", + "unorm": "^1.4.1", + "xcode": "^2.0.0", + "xml-escape": "^1.1.0" } }, - "engine.io-parser": { + "cordova-plugin-android-permissions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cordova-plugin-android-permissions/-/cordova-plugin-android-permissions-1.0.0.tgz", + "integrity": "sha1-nnwRa+Zo6336QUkbE9jUfalUgUk=" + }, + "cordova-plugin-device": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cordova-plugin-device/-/cordova-plugin-device-2.0.3.tgz", + "integrity": "sha512-Jb3V72btxf3XHpkPQsGdyc8N6tVBYn1vsxSFj43fIz9vonJDUThYPCJJHqk6PX6N4dJw6I4FjxkpfCR4LDYMlw==" + }, + "cordova-plugin-ionic-keyboard": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "dev": true, + "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-keyboard/-/cordova-plugin-ionic-keyboard-2.1.3.tgz", + "integrity": "sha512-6ucQ6FdlLdBm8kJfFnzozmBTjru/0xekHP/dAhjoCZggkGRlgs8TsUJFkxa/bV+qi7Dlo50JjmpE4UMWAO+aOQ==" + }, + "cordova-plugin-ionic-webview": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/cordova-plugin-ionic-webview/-/cordova-plugin-ionic-webview-4.1.1.tgz", + "integrity": "sha512-y8drBhMdkHKUr0zu+UGkFGsDrkCsxjbCd3RzzlyDxcEzdHWvasRM5gyDiKBHkziT2iHYzEAjXwkT1ZXKU3OY9Q==" + }, + "cordova-plugin-iosrtc": { + "version": "git+https://github.com/OpenVidu/cordova-plugin-iosrtc.git#b458a666b5a1879460585168fc2242e9fd38a584", + "from": "git+https://github.com/OpenVidu/cordova-plugin-iosrtc.git", "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" + "debug": "^2.6.8", + "domready": "^1.0.8", + "random-number": "^0.0.7", + "yaeti": "^0.0.6" } }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, + "cordova-plugin-splashscreen": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-5.0.3.tgz", + "integrity": "sha512-rnoDXMDfzoeHDBvsnu6JmzDE/pV5YJCAfc5hYX/Mb2BIXGgSjFJheByt0tU6kp3Wl40tSyFX4pYfBwFblBGyRg==" + }, + "cordova-plugin-statusbar": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/cordova-plugin-statusbar/-/cordova-plugin-statusbar-2.4.3.tgz", + "integrity": "sha512-ThmXzl6QIKWFXf4wWw7Q/zpB+VKkz3VM958+5A0sXD4jmR++u7KnGttLksXshVwWr6lvGwUebLYtIyXwS4Ovcg==" + }, + "cordova-plugin-whitelist": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/cordova-plugin-whitelist/-/cordova-plugin-whitelist-1.3.4.tgz", + "integrity": "sha512-EYC5eQFVkoYXq39l7tYKE6lEjHJ04mvTmKXxGL7quHLdFPfJMNzru/UYpn92AOfpl3PQaZmou78C7EgmFOwFQQ==" + }, + "cordova-serve": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cordova-serve/-/cordova-serve-3.0.0.tgz", + "integrity": "sha512-h479g/5a0PXn//yiFuMrD5MDEbB+mtihNkWcE6uD/aCh/6z0FRZ9sWH3NfZbHDB+Bp1yGLYsjbH8LZBL8KOQ0w==", "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" + "chalk": "^2.4.1", + "compression": "^1.6.0", + "express": "^4.13.3", + "opn": "^5.3.0", + "which": "^1.3.0" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true + "core-js": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", + "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" }, - "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { - "prr": "~1.0.1" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, - "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==", + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "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==", - "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" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, - "es-to-primitive": { + "create-hash": { "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==", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "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 - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", "dev": true }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "css-selector-tokenizer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", "dev": true, "requires": { - "original": "^1.0.0" + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" } }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "through": "X.X.X" } }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "damerau-levenshtein": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "assert-plus": "^1.0.0" } }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "ms": "2.0.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "execa": "^1.0.0", + "ip-regex": "^2.1.0" } }, - "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "strip-bom": "^3.0.0" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "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==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -4034,831 +4265,1017 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, - "fast-json-parse": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", - "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==" + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "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=", + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "fastparse": { + "depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dependency-graph": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", "dev": true }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "file-loader": { + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-indent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.0.0.tgz", - "integrity": "sha512-roAbL6IdSGczwfXxhMi6Zq+jD4IfUpL0jWHD7fvmjdOVb7xBfdRUHe4LpBgO23VtVK5AW1OlWZo0p34Jvx3iWg==", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "loader-utils": "^1.2.2", - "schema-utils": "^1.0.0" + "repeating": "^2.0.0" } }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true, - "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" - } + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "asap": "^2.0.0", + "wrappy": "1" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "path-type": "^3.0.0" } }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", "dev": true }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", "dev": true, "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" } }, - "follow-redirects": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", - "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", "dev": true, "requires": { - "debug": "^3.2.6" - }, - "dependencies": { - "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" - } - }, - "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 - } + "buffer-indexof": "^1.0.0" } }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, "requires": { - "is-callable": "^1.1.3" + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "domready": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", + "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { - "for-in": "^1.0.1" + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.203", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.203.tgz", + "integrity": "sha512-Z1FjJKEBhYrCNmnususVk8khiBabVI/bSJB/295V4ghVt4MFmtbP+mXgRZLQZinEBI469U6FtiGgpXnlLs6qiQ==", + "dev": true }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, + "elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha1-mskb5uUvtuYkTE5UpKw+2K6OKcA=", "requires": { - "map-cache": "^0.2.2" + "sax": "1.1.4" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "elliptic": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "dev": true, "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.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 }, - "fs-minipass": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", - "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, "requires": { - "minipass": "^2.2.1" + "iconv-lite": "~0.4.13" } }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "once": "^1.4.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "endent": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/endent/-/endent-1.3.0.tgz", + "integrity": "sha512-C8AryqPPwtydqcpO5AF6k9Bd1EpFkQtvsefJqS3y3n8TG13Jy63MascDxTOULZYqrUde+dK6BjNc6LIMr3iI2A==", + "requires": { + "dedent": "^0.7.0", + "fast-json-parse": "^1.0.3", + "objectorarray": "^1.0.3" + } }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, - "optional": true, "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": 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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true }, - "minimatch": { - "version": "3.0.4", - "bundled": true, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, - "optional": true, "requires": { - "brace-expansion": "^1.1.7" + "ms": "2.0.0" } }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, - "optional": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } - }, - "minizlib": { + } + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, - "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "ms": "2.0.0" } }, - "npmlog": { - "version": "4.1.2", - "bundled": true, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, - "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "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==", + "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==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "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 + }, + "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 + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { - "wrappy": "1" + "is-descriptor": "^0.1.0" } }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "is-extendable": "^0.1.0" } - }, - "path-is-absolute": { + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "optional": true, "requires": { - "glob": "^7.1.3" + "is-plain-object": "^2.0.4" } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "is-descriptor": "^1.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "is-extendable": "^0.1.0" } }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { - "ansi-regex": "^2.0.0" + "kind-of": "^6.0.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "kind-of": "^6.0.0" } }, - "util-deprecate": { + "is-descriptor": { "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-parse": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", + "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==" + }, + "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 + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "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-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.0.0.tgz", + "integrity": "sha512-roAbL6IdSGczwfXxhMi6Zq+jD4IfUpL0jWHD7fvmjdOVb7xBfdRUHe4LpBgO23VtVK5AW1OlWZo0p34Jvx3iWg==", + "dev": true, + "requires": { + "loader-utils": "^1.2.2", + "schema-utils": "^1.0.0" + } + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dev": true, + "requires": { + "debug": "^3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, - "optional": true + "requires": { + "ms": "^2.1.1" + } }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", + "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", + "dev": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", + "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4883,18 +5300,6 @@ "dev": true, "requires": { "pump": "^3.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } } }, "get-value": { @@ -4975,9 +5380,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "handle-thing": { "version": "2.0.0", @@ -5092,6 +5497,26 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -5180,6 +5605,13 @@ "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "http-parser-js": { @@ -5250,12 +5682,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", "dev": true, "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" }, "dependencies": { @@ -5269,9 +5701,9 @@ } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -5393,9 +5825,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -5403,6 +5835,44 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "inquirer": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", + "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "internal-ip": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", @@ -5422,6 +5892,12 @@ "loose-envify": "^1.0.0" } }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, "ionicons": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-4.6.2.tgz", @@ -5503,12 +5979,12 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { @@ -5594,13 +6070,10 @@ } }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "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": "4.0.1", @@ -5612,47 +6085,33 @@ } }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", "dev": true, "requires": { - "is-path-inside": "^1.0.0" + "is-path-inside": "^2.1.0" } }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "path-is-inside": "^1.0.2" } }, "is-plain-obj": { @@ -6087,9 +6546,9 @@ } }, "jszip": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.1.tgz", - "integrity": "sha512-iCMBbo4eE5rb1VCpm5qXOAaUiRKRUKiItn8ah2YQQx9qymmSAY98eyQfioChEYcVQLh0zxJ3wS4A0mh90AVPvw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz", + "integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==", "dev": true, "requires": { "lie": "~3.3.0", @@ -6133,122 +6592,17 @@ "useragent": "2.3.0" }, "dependencies": { - "anymatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.0.3.tgz", - "integrity": "sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", - "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", - "dev": true, - "requires": { - "anymatch": "^3.0.1", - "braces": "^3.0.2", - "fsevents": "^2.0.6", - "glob-parent": "^5.0.0", - "is-binary-path": "^2.1.0", - "is-glob": "^4.0.1", - "normalize-path": "^3.0.0", - "readdirp": "^3.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", - "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "readdirp": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.1.tgz", - "integrity": "sha512-XXdSXZrQuvqoETj50+JAitxz1UPdt5dupjT6T5nVB+WvjMv2XKYj+s7hPeAVCXvmJrL36O4YYyWlIC3an2ePiQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, "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 - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -6307,6 +6661,15 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, "less": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", @@ -6391,9 +6754,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash.clonedeep": { @@ -6608,6 +6971,90 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "miller-rabin": { @@ -6716,24 +7163,12 @@ "pumpify": "^1.3.3", "stream-each": "^1.1.0", "through2": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -6956,13 +7391,10 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "normalize-range": { "version": "0.1.2", @@ -7205,11 +7637,11 @@ } }, "openvidu-browser": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.10.0.tgz", - "integrity": "sha512-D+Eww0fh4omsNeeNSelj37s/mmvCe18MhtNsoaWXRSKclBWPrDpab6Ct4wonH5zpQK5sVCWG+KwEnDoBd1Y0Vg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.11.0.tgz", + "integrity": "sha512-dXnzHA9gf0Fhl88YijmPbFT/d7ERUHOMrqGObVeDc5NvG/7y2HCFafb/42O/mZ86IkBZnmqSrl6Q63aNlUZ2iA==", "requires": { - "@types/node": "12.0.3", + "@types/node": "12.6.8", "@types/platform": "1.3.2", "freeice": "2.2.2", "hark": "1.2.3", @@ -7219,93 +7651,38 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" - }, - "@types/fs-extra": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz", - "integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", - "requires": { - "handlebars": "*" - } - }, - "@types/highlight.js": { - "version": "9.12.3", - "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", - "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==" - }, - "@types/lodash": { - "version": "4.14.132", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.132.tgz", - "integrity": "sha512-RNUU1rrh85NgUJcjOOr96YXr+RHwInGbaQCZmlitqOaCKXffj8bh+Zxwuq5rjDy5OgzFldDVoqk4pyLEDiwxIw==" - }, - "@types/marked": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz", - "integrity": "sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==" - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.3.tgz", - "integrity": "sha512-zkOxCS/fA+3SsdA+9Yun0iANxzhQRiNwTvJSr6N95JhuJ/x27z9G2URx1Jpt3zYFfCGUXZGL5UDxt5eyLE7wgw==" + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==" }, "@types/platform": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.2.tgz", "integrity": "sha512-Tn6OuJDAG7bJbyi4R7HqcxXp1w2lmIxVXqyNhPt1Bm0FO2EWIi3CI87JVzF7ncqK0ZMPuUycS3wTMIk85EeF1Q==" }, - "@types/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==", - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -7321,9 +7698,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -7342,9 +7719,9 @@ } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, "amdefine": { "version": "1.0.1", @@ -7518,6 +7895,14 @@ "postcss": "~4.1.12" } }, + "backbone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", + "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", + "requires": { + "underscore": ">=1.8.3" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -7669,9 +8054,9 @@ } }, "browserify": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", - "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", + "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -7866,9 +8251,9 @@ } }, "caniuse-db": { - "version": "1.0.30000971", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000971.tgz", - "integrity": "sha512-ubSZfYXO2KMYtCVmDez82mjodeZa+mBYWAnBMAmFBPAn4C2PY4SD0eC/diYQD4Rj1K+WNdp0vr0JDtm0SQ6GNg==" + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000986.tgz", + "integrity": "sha512-8SKJ12AFwG0ReMjPwRH+keFsX/ucw2bi6LC7upeXBvxjgrMqHaTxgYhkRGm+eOwUWvVcqXDgqM7QNlRJMhvXZg==" }, "chalk": { "version": "2.4.2", @@ -8113,9 +8498,9 @@ }, "dependencies": { "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" } } }, @@ -8296,9 +8681,9 @@ } }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -8614,11 +8999,11 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -9197,9 +9582,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "grunt": { "version": "1.0.4", @@ -9453,11 +9838,11 @@ }, "dependencies": { "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } } } @@ -9521,11 +9906,11 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "chalk": { @@ -9735,9 +10120,9 @@ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=" }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "https-browserify": { "version": "1.0.0", @@ -9775,9 +10160,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -9987,6 +10372,11 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-base64": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", @@ -10097,9 +10487,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.memoize": { "version": "3.0.4", @@ -10120,6 +10510,11 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" }, + "lunr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.6.tgz", + "integrity": "sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -10147,9 +10542,9 @@ } }, "marked": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", - "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" }, "maxmin": { "version": "2.1.0", @@ -10287,9 +10682,9 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -10721,9 +11116,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -10837,6 +11232,11 @@ "util-deprecate": "~1.0.1" }, "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -10907,9 +11307,9 @@ } }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } @@ -10951,9 +11351,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-json-parse": { "version": "1.0.1", @@ -10984,9 +11384,9 @@ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -11196,9 +11596,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -11282,6 +11682,13 @@ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -11381,9 +11788,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -11460,14 +11867,14 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", + "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -11475,7 +11882,7 @@ "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -11510,50 +11917,43 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.14.2.tgz", - "integrity": "sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ==", - "requires": { - "@types/fs-extra": "^5.0.3", - "@types/handlebars": "^4.0.38", - "@types/highlight.js": "^9.12.3", - "@types/lodash": "^4.14.110", - "@types/marked": "^0.4.0", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.15.0.tgz", + "integrity": "sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw==", + "requires": { "@types/minimatch": "3.0.3", - "@types/shelljs": "^0.8.0", - "fs-extra": "^7.0.0", - "handlebars": "^4.0.6", - "highlight.js": "^9.13.1", - "lodash": "^4.17.10", - "marked": "^0.4.0", + "fs-extra": "^8.1.0", + "handlebars": "^4.1.2", + "highlight.js": "^9.15.8", + "lodash": "^4.17.15", + "marked": "^0.7.0", "minimatch": "^3.0.0", - "progress": "^2.0.0", - "shelljs": "^0.8.2", - "typedoc-default-themes": "^0.5.0", - "typescript": "3.2.x" - }, - "dependencies": { - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==" - } + "progress": "^2.0.3", + "shelljs": "^0.8.3", + "typedoc-default-themes": "^0.6.0", + "typescript": "3.5.x" } }, "typedoc-default-themes": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz", - "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.6.0.tgz", + "integrity": "sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw==", + "requires": { + "backbone": "^1.4.0", + "jquery": "^3.4.1", + "lunr": "^2.3.6", + "underscore": "^1.9.1" + } }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==" + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==" }, "uglify-js": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", - "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" @@ -11588,6 +11988,11 @@ "xtend": "^4.0.1" } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -11598,35 +12003,14 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "universalify": { @@ -11712,6 +12096,13 @@ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "util-deprecate": { @@ -11747,11 +12138,12 @@ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -11769,9 +12161,9 @@ } }, "wildemitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.0.tgz", - "integrity": "sha1-Kd06ctaZw+J53QIcPNIVC4LJohE=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.1.tgz", + "integrity": "sha512-UMmSUoIQSir+XbBpTxOTS53uJ8s/lVhADCkEbhfRjUGFDPme/XGOb0sBWLx5sTz7Wx/2+TlAw1eK9O5lw5PiEw==" }, "wolfy87-eventemitter": { "version": "5.2.6", @@ -11803,1583 +12195,2091 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pacote": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.1.tgz", + "integrity": "sha512-Zqvczvf/zZ7QNosdE9uTC7SRuvSs9tFqRkF6cJl+2HH7COBnx4BRAGpeXJlrbN+mM0CMHpbi620xdEHhCflghA==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^11.3.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^4.0.1", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^2.2.3", + "npm-registry-fetch": "^3.8.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.8", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + } + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "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=" + }, + "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-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "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==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } } }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, "requires": { - "is-wsl": "^1.1.0" + "find-up": "^3.0.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "plist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "requires": { + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", + "xmldom": "0.1.x" + } + }, + "portfinder": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", + "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" }, "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true } } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "postcss": { + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", + "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", "dev": true, "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" }, "dependencies": { - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "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 }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "invert-kv": "^2.0.0" + "has-flag": "^3.0.0" } } } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" } }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { + "postcss-load-config": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" } }, - "p-locate": { + "postcss-loader": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" } }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.0" - }, - "dependencies": { - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - } - } + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, - "pacote": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.1.tgz", - "integrity": "sha512-Zqvczvf/zZ7QNosdE9uTC7SRuvSs9tFqRkF6cJl+2HH7COBnx4BRAGpeXJlrbN+mM0CMHpbi620xdEHhCflghA==", + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, + "optional": true, "requires": { - "bluebird": "^3.5.3", - "cacache": "^11.3.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^4.0.1", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^2.2.3", - "npm-registry-fetch": "^3.8.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.8", - "unique-filename": "^1.1.1", - "which": "^1.3.1" + "asap": "~2.0.3" } }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, - "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", "dev": true, "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + } } }, - "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, + "properties-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz", + "integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=", "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "string.prototype.codepointat": "^0.2.0" } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "protoduck": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", "dev": true, "requires": { - "better-assert": "~1.0.0" + "genfun": "^5.0.0" } }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "protractor": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.2.tgz", + "integrity": "sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==", "dev": true, "requires": { - "better-assert": "~1.0.0" + "@types/q": "^0.0.32", + "@types/selenium-webdriver": "^3.0.0", + "blocking-proxy": "^1.0.0", + "browserstack": "^1.5.1", + "chalk": "^1.1.3", + "glob": "^7.0.3", + "jasmine": "2.8.0", + "jasminewd2": "^2.1.0", + "optimist": "~0.6.0", + "q": "1.4.1", + "saucelabs": "^1.5.0", + "selenium-webdriver": "3.6.0", + "source-map-support": "~0.4.0", + "webdriver-js-extender": "2.1.0", + "webdriver-manager": "^12.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "webdriver-manager": { + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.5.tgz", + "integrity": "sha512-f1apDjMpZ8SHlXtXGzqBxOjV+WQcDRz5PN7pWScgjXS7vhUIFcM3V89Shetf4A04n8DDR2MxiVQq6JproFcRZw==", + "dev": true, + "requires": { + "adm-zip": "^0.4.9", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + } + } } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "path-dirname": { + "pseudomap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "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=", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "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=" - }, - "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=", + "psl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "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==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { - "pify": "^3.0.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } } } }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", "dev": true, "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, - "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "random-number": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/random-number/-/random-number-0.0.7.tgz", + "integrity": "sha1-fWKxAK3pDxNCNarYwGotLfpc/0g=" }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { - "pinkie": "^2.0.0" + "safe-buffer": "^5.1.0" } }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - } + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, - "plist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", - "requires": { - "base64-js": "^1.2.3", - "xmlbuilder": "^9.0.7", - "xmldom": "0.1.x" - } + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, - "portfinder": { - "version": "1.0.21", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", - "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", - "dev": true, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" } } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "raw-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz", + "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + } }, - "postcss": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", - "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "pify": "^2.3.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, - "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "read-package-json": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", + "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "slash": "^1.0.0" + } + }, + "read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", "dev": true, "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" } }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" } }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "readdirp": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.1.tgz", + "integrity": "sha512-XXdSXZrQuvqoETj50+JAitxz1UPdt5dupjT6T5nVB+WvjMv2XKYj+s7hPeAVCXvmJrL36O4YYyWlIC3an2ePiQ==", "dev": true, - "optional": true, "requires": { - "asap": "~2.0.3" + "picomatch": "^2.0.4" } }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, - "promise-retry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", - "dev": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - } + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true }, - "properties-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz", - "integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=", - "requires": { - "string.prototype.codepointat": "^0.2.0" - } + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true }, - "protoduck": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", - "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "genfun": "^5.0.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, - "protractor": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.2.tgz", - "integrity": "sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==", + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { - "@types/q": "^0.0.32", - "@types/selenium-webdriver": "^3.0.0", - "blocking-proxy": "^1.0.0", - "browserstack": "^1.5.1", - "chalk": "^1.1.3", - "glob": "^7.0.3", - "jasmine": "2.8.0", - "jasminewd2": "^2.1.0", - "optimist": "~0.6.0", - "q": "1.4.1", - "saucelabs": "^1.5.0", - "selenium-webdriver": "3.6.0", - "source-map-support": "~0.4.0", - "webdriver-js-extender": "2.1.0", - "webdriver-manager": "^12.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "webdriver-manager": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.4.tgz", - "integrity": "sha512-aNUzdimlHSl3EotUTdE2QwP9sBUjZgWPCy8C+m1wMmF9jBDKuO/24nnpr2O25Db8dYtsjvj9drPTpSIGqRrNnQ==", - "dev": true, - "requires": { - "adm-zip": "^0.4.9", - "chalk": "^1.1.1", - "del": "^2.2.0", - "glob": "^7.0.3", - "ini": "^1.3.4", - "minimist": "^1.2.0", - "q": "^1.4.1", - "request": "^2.87.0", - "rimraf": "^2.5.2", - "semver": "^5.3.0", - "xml2js": "^0.4.17" - } - } + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } } }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, - "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { + "repeating": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "is-finite": "^1.0.0" } }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } } }, - "punycode": { + "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "requires": { + "path-parse": "^1.0.6" + } }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "resolve-from": "^3.0.0" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, - "querystring-es3": { + "resolve-url": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "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" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "~2.3.4" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "random-number": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/random-number/-/random-number-0.0.7.tgz", - "integrity": "sha1-fWKxAK3pDxNCNarYwGotLfpc/0g=" + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "glob": "^7.1.3" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + "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" + } }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - } + "ret": "~0.1.10" } }, - "raw-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz", - "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==", + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sass": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.22.2.tgz", + "integrity": "sha512-enuQuy/CbfrZLA2vOy9tB7CK7pP5bZllnMbr5nPGWCFelwt0EMUVGC11gsv9rybkWc8pp/NKVY/c5+AKyjbnXg==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0" + "chokidar": ">=2.0.0 <4.0.0" } }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "sass-loader": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", + "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", "dev": true, "requires": { - "pify": "^2.3.0" + "clone-deep": "^2.0.1", + "loader-utils": "^1.0.1", + "lodash.tail": "^4.1.1", + "neo-async": "^2.5.0", + "pify": "^3.0.0", + "semver": "^5.5.0" }, "dependencies": { "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, - "read-package-json": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", - "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", "dev": true, "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", - "slash": "^1.0.0" + "https-proxy-agent": "^2.2.1" } }, - "read-package-tree": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", - "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk=" + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "dependencies": { + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + } } }, - "readdir-scoped-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", - "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "selfsigned": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", + "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", "dev": true, "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" + "node-forge": "0.7.5" } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "semver-dsl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", + "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "semver": "^5.3.0" } }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true - }, - "regenerate": { + "semver-intersect": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true + "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", + "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", + "dev": true, + "requires": { + "semver": "^5.0.0" + } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "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==" + } + } + }, + "serialize-javascript": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", + "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", "dev": true }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } } }, - "regexpu-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", - "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", - "dev": true, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" } }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { - "jsesc": "~0.5.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "is-finite": "^1.0.0" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "shallow-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", + "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", "dev": true, "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "is-extendable": "^0.1.1", + "kind-of": "^5.0.0", + "mixin-object": "^2.0.1" }, "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "path-parse": "^1.0.6" + "shebang-regex": "^1.0.0" } }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.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=" }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=" }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "restore-cursor": { + "simctl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, + "resolved": "https://registry.npmjs.org/simctl/-/simctl-2.0.0.tgz", + "integrity": "sha512-5rB7rN4N3b0z0nFdy9eczVssXqrv2aAgdVRksPVqVoiDtvXmfzNvebp3EMdId2sAUzXIflarQlx4P0hjVQEzKQ==", "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "shelljs": "^0.2.6", + "tail": "^0.4.0" + }, + "dependencies": { + "shelljs": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz", + "integrity": "sha1-kEktcv/MgVmXa6umL7D2iE8MM3g=" + } } }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "simple-plist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.0.0.tgz", + "integrity": "sha512-043L2rO80LVF7zfZ+fqhsEkoJFvW8o59rt/l4ctx1TJWoTx7/jkiS1R5TatD15Z1oYnuLJytzE7gcnnBuIPL2g==", "requires": { - "through": "~2.3.4" + "bplist-creator": "0.0.7", + "bplist-parser": "0.1.1", + "plist": "^3.0.1" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, - "rfdc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", - "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "smart-buffer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", "dev": true }, - "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" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "is-promise": "^2.1.0" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "requires": { - "tslib": "^1.9.0" + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "dev": true, "requires": { - "ret": "~0.1.10" + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true }, - "sass": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.22.2.tgz", - "integrity": "sha512-enuQuy/CbfrZLA2vOy9tB7CK7pP5bZllnMbr5nPGWCFelwt0EMUVGC11gsv9rybkWc8pp/NKVY/c5+AKyjbnXg==", + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "dev": true, "requires": { - "chokidar": ">=2.0.0 <4.0.0" + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, - "sass-loader": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", - "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { - "clone-deep": "^2.0.1", - "loader-utils": "^1.0.1", - "lodash.tail": "^4.1.1", - "neo-async": "^2.5.0", - "pify": "^3.0.0", - "semver": "^5.5.0" + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", "dev": true } } }, - "saucelabs": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", - "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", "dev": true, "requires": { - "https-proxy-agent": "^2.2.1" + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "sockjs-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "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" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "sax": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", - "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk=" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "socks": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", + "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "ip": "^1.1.5", + "smart-buffer": "4.0.2" } }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selenium-webdriver": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", - "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "socks-proxy-agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", "dev": true, "requires": { - "jszip": "^3.1.3", - "rimraf": "^2.5.4", - "tmp": "0.0.30", - "xml2js": "^0.4.17" + "agent-base": "~4.2.1", + "socks": "~2.3.2" }, "dependencies": { - "tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "os-tmpdir": "~1.0.1" + "es6-promisify": "^5.0.0" } } } }, - "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", "dev": true, "requires": { - "node-forge": "0.7.5" + "is-plain-obj": "^1.0.0" } }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true }, - "semver-dsl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", - "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "source-map-loader": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", + "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", "dev": true, "requires": { - "semver": "^5.3.0" + "async": "^2.5.0", + "loader-utils": "^1.1.0" } }, - "semver-intersect": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", - "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "semver": "^5.0.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" }, "dependencies": { - "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==" + "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 } } }, - "serialize-javascript": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } + "sourcemap-codec": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", + "dev": true }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "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": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "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 }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "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": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "spdy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" }, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } } } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "speed-measure-webpack-plugin": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz", + "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==", + "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "chalk": "^2.0.1" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shelljs": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=" + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "simctl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simctl/-/simctl-2.0.0.tgz", - "integrity": "sha512-5rB7rN4N3b0z0nFdy9eczVssXqrv2aAgdVRksPVqVoiDtvXmfzNvebp3EMdId2sAUzXIflarQlx4P0hjVQEzKQ==", + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { - "shelljs": "^0.2.6", - "tail": "^0.4.0" - }, - "dependencies": { - "shelljs": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz", - "integrity": "sha1-kEktcv/MgVmXa6umL7D2iE8MM3g=" - } + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, - "simple-plist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.0.0.tgz", - "integrity": "sha512-043L2rO80LVF7zfZ+fqhsEkoJFvW8o59rt/l4ctx1TJWoTx7/jkiS1R5TatD15Z1oYnuLJytzE7gcnnBuIPL2g==", + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, "requires": { - "bplist-creator": "0.0.7", - "bplist-parser": "0.1.1", - "plist": "^3.0.1" + "figgy-pudding": "^3.5.1" } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "smart-buffer": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", - "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -13390,578 +14290,648 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "streamroller": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.6.tgz", + "integrity": "sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==", + "dev": true, + "requires": { + "async": "^2.6.2", + "date-format": "^2.0.0", + "debug": "^3.2.6", + "fs-extra": "^7.0.1", + "lodash": "^4.17.14" }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "ms": "^2.1.1" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "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": { - "kind-of": "^3.2.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "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": { - "is-buffer": "^1.1.5" + "ansi-regex": "^3.0.0" } } } }, - "socket.io": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", - "dev": true, + "string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", "requires": { - "debug": "~3.1.0", - "engine.io": "~3.2.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.1", - "socket.io-parser": "~3.2.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" } }, - "socket.io-adapter": { + "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "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=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", "dev": true, "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + } + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "dev": true, + "requires": { + "css-parse": "1.7.x", + "debug": "*", + "glob": "7.0.x", + "mkdirp": "0.5.x", + "sax": "0.5.x", + "source-map": "0.1.x" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", "dev": true }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { - "ms": "2.0.0" + "amdefine": ">=0.0.4" } } } }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "tail": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/tail/-/tail-0.4.0.tgz", + "integrity": "sha1-0p3nJ1DMmdseBTr/E8NZ7PtxMAI=" + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tape": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz", + "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==", + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.4", + "has": "~1.0.3", + "inherits": "~2.0.4", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.11.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + } + }, + "tar": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.5", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "terser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", + "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", "dev": true, "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "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 } } }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { + "terser-webpack-plugin": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", + "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", "dev": true, "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" + "cacache": "^11.3.2", + "find-cache-dir": "^2.0.0", + "is-wsl": "^1.1.0", + "loader-utils": "^1.2.3", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "source-map": "^0.6.1", + "terser": "^4.0.0", + "webpack-sources": "^1.3.0", + "worker-farm": "^1.7.0" }, "dependencies": { - "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" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "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 } } }, - "socks": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", - "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { - "ip": "^1.1.5", - "smart-buffer": "4.0.2" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "socks-proxy-agent": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", - "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "dev": true, "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" + "setimmediate": "^1.0.4" } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "is-plain-obj": "^1.0.0" + "os-tmpdir": "~1.0.2" } }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "dev": true }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, - "source-map-loader": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", - "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", - "dev": true, - "requires": { - "async": "^2.5.0", - "loader-utils": "^1.1.0" - } - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "kind-of": "^3.0.2" }, "dependencies": { - "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 + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sourcemap-codec": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", - "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.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==", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "is-number": "^7.0.0" } }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, - "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" + "psl": "^1.1.24", + "punycode": "^1.4.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true } } }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "tree-kill": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", + "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "ts-node": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", + "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", "dev": true, "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "tslint": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", + "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } } } }, - "speed-measure-webpack-plugin": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz", - "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==", + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, "requires": { - "chalk": "^2.0.1" + "tslib": "^1.8.1" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "extend-shallow": "^3.0.0" + "safe-buffer": "^5.0.1" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" } }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "typescript": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", + "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", + "dev": true + }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, + "optional": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "commander": "~2.20.0", + "source-map": "~0.6.1" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "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, - "requires": { - "is-descriptor": "^0.1.0" - } + "optional": true } } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" } }, - "stream-buffers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" + "unique-slug": "^2.0.0" } }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + "imurmurhash": "^0.1.4" } }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "streamroller": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.6.tgz", - "integrity": "sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==", + "universal-analytics": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz", + "integrity": "sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==", "dev": true, "requires": { - "async": "^2.6.2", - "date-format": "^2.0.0", - "debug": "^3.2.6", - "fs-extra": "^7.0.1", - "lodash": "^4.17.14" + "debug": "^3.0.0", + "request": "^2.88.0", + "uuid": "^3.0.0" }, "dependencies": { "debug": { @@ -13973,12 +14943,6 @@ "ms": "^2.1.1" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13987,314 +14951,896 @@ } } }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.codepointat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", - "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" }, - "strip-eof": { + "unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "style-loader": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", - "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0" - } + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } } }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } } } }, - "stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "when": "~3.6.x" - } + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { - "has-flag": "^3.0.0" + "punycode": "^2.1.0" } }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - }, - "tail": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/tail/-/tail-0.4.0.tgz", - "integrity": "sha1-0p3nJ1DMmdseBTr/E8NZ7PtxMAI=" - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, - "tape": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.10.2.tgz", - "integrity": "sha512-mgl23h7W2yuk3N85FOYrin2OvThTYWdwbk6XQ1pr2PMJieyW2FM/4Bu/+kD/wecb3aZ0Enm+Syinyq467OPq2w==", + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.4", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.10.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } } }, - "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "terser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", - "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", "dev": true, "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" + "lru-cache": "4.1.x", + "tmp": "0.0.x" }, "dependencies": { - "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 - }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "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": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } }, - "terser-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, "requires": { - "cacache": "^11.3.2", - "find-cache-dir": "^2.0.0", - "is-wsl": "^1.1.0", - "loader-utils": "^1.2.3", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "source-map": "^0.6.1", - "terser": "^4.0.0", - "webpack-sources": "^1.3.0", - "worker-farm": "^1.7.0" + "inherits": "2.0.3" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true } } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "util-promisify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", + "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", "dev": true, "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "object.getownpropertydescriptors": "^2.0.3" } }, - "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", - "dev": true + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "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": { - "setimmediate": "^1.0.4" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "builtins": "^1.0.3" } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", "dev": true }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" }, "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -14303,670 +15849,835 @@ "requires": { "is-buffer": "^1.1.5" } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "tree-kill": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", - "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - }, - "tslint": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", - "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", - "dev": true - }, - "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "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, - "optional": true - } - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } } } }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "requires": { - "unique-slug": "^2.0.0" + "minimalistic-assert": "^1.0.0" } }, - "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "webdriver-js-extender": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", + "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", "dev": true, "requires": { - "imurmurhash": "^0.1.4" + "@types/selenium-webdriver": "^3.0.0", + "selenium-webdriver": "^3.0.1" } }, - "universal-analytics": { - "version": "0.4.20", - "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz", - "integrity": "sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==", + "webpack": { + "version": "4.35.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.35.2.tgz", + "integrity": "sha512-TZAmorNymV4q66gAM/h90cEjG+N3627Q2MnkSgKlX/z3DlNVKUtqy57lz1WmZU2+FUZwzM+qm7cGaO95PyrX5A==", "dev": true, "requires": { - "debug": "^3.0.0", - "request": "^2.88.0", - "uuid": "^3.0.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.0.5", + "acorn-dynamic-import": "^4.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^1.0.0", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" + } + }, + "webpack-core": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", + "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", + "dev": true, + "requires": { + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "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": { - "ms": "^2.1.1" + "amdefine": ">=0.0.4" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unorm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", - "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "webpack-dev-middleware": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", + "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.2", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + } + } }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "webpack-dev-server": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz", + "integrity": "sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew==", "dev": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.6", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "^0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "killable": "^1.0.1", + "loglevel": "^1.6.3", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.20", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.4", + "semver": "^6.1.1", + "serve-index": "^1.9.1", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.0", + "webpack-log": "^2.0.0", + "yargs": "12.0.5" }, "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, "dev": true, + "optional": true, "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - }, - "dependencies": { - "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" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util-promisify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", - "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "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" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webdriver-js-extender": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", - "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", - "dev": true, - "requires": { - "@types/selenium-webdriver": "^3.0.0", - "selenium-webdriver": "^3.0.1" - } - }, - "webpack": { - "version": "4.35.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.35.2.tgz", - "integrity": "sha512-TZAmorNymV4q66gAM/h90cEjG+N3627Q2MnkSgKlX/z3DlNVKUtqy57lz1WmZU2+FUZwzM+qm7cGaO95PyrX5A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^1.0.0", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - } - }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", - "dev": true, - "requires": { - "source-list-map": "~0.1.7", - "source-map": "~0.4.1" - }, - "dependencies": { - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "binary-extensions": "^1.0.0" } - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", - "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.2", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true - } - } - }, - "webpack-dev-server": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz", - "integrity": "sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.6", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "^0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "killable": "^1.0.1", - "loglevel": "^1.6.3", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.20", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.4", - "semver": "^6.1.1", - "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "^4.0.0", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.0", - "webpack-log": "^2.0.0", - "yargs": "12.0.5" - }, - "dependencies": { - "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "kind-of": "^3.0.2" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "ms": "^2.1.1" + "is-buffer": "^1.1.5" } }, "ms": { @@ -14975,11 +16686,16 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } }, "semver": { "version": "6.3.0", @@ -14995,6 +16711,16 @@ "requires": { "has-flag": "^3.0.0" } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -15113,6 +16839,28 @@ "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "wrappy": { @@ -15170,9 +16918,9 @@ "dev": true }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "y18n": { @@ -15210,93 +16958,6 @@ "which-module": "^2.0.0", "y18n": "^3.2.1 || ^4.0.0", "yargs-parser": "^11.1.1" - }, - "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 - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.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 - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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" - } - }, - "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" - } - } } }, "yargs-parser": { diff --git a/openvidu-ionic/package.json b/openvidu-ionic/package.json index d7f869101..396021fea 100644 --- a/openvidu-ionic/package.json +++ b/openvidu-ionic/package.json @@ -1,6 +1,6 @@ { "name": "openvidu-ionic", - "version": "2.10.0", + "version": "2.11.0", "author": "OpenVidu", "homepage": "https://openvidu.io/", "scripts": { @@ -38,7 +38,7 @@ "cordova-plugin-whitelist": "1.3.4", "core-js": "3.1.4", "ios-deploy": "1.9.4", - "openvidu-browser": "2.10.0", + "openvidu-browser": "2.11.0", "rxjs": "6.5.2", "xcode": "2.0.0", "zone.js": "0.9.1" @@ -93,4 +93,4 @@ "browser" ] } -} \ No newline at end of file +} diff --git a/openvidu-js-java/docker/Dockerfile b/openvidu-js-java/docker/Dockerfile index 7031b1d48..6479b698c 100644 --- a/openvidu-js-java/docker/Dockerfile +++ b/openvidu-js-java/docker/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:16.04 LABEL maintainer="openvidu@gmail.com" # Install Kurento Media Server (KMS) -RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.10.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ +RUN echo "deb [arch=amd64] http://ubuntu.openvidu.io/6.11.0 xenial kms6" | tee /etc/apt/sources.list.d/kurento.list \ && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83 \ && apt-get update \ && apt-get -y install kurento-media-server \ diff --git a/openvidu-js-java/pom.xml b/openvidu-js-java/pom.xml index e1b61bda9..bae27ba54 100644 --- a/openvidu-js-java/pom.xml +++ b/openvidu-js-java/pom.xml @@ -5,7 +5,7 @@ io.openvidu openvidu-js-java - 2.10.0 + 2.11.0 jar openvidu-js-java @@ -55,7 +55,7 @@ io.openvidu openvidu-java-client - 2.10.0 + 2.11.0 diff --git a/openvidu-js-java/src/main/resources/static/index.html b/openvidu-js-java/src/main/resources/static/index.html index d1ed6810d..d0285f3e9 100644 --- a/openvidu-js-java/src/main/resources/static/index.html +++ b/openvidu-js-java/src/main/resources/static/index.html @@ -14,7 +14,7 @@ - + + + diff --git a/openvidu-mvc-node/package-lock.json b/openvidu-mvc-node/package-lock.json index c1cf51384..2360dd725 100644 --- a/openvidu-mvc-node/package-lock.json +++ b/openvidu-mvc-node/package-lock.json @@ -1,6 +1,6 @@ { "name": "openvidu-mvc-node", - "version": "2.9.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -337,9 +337,9 @@ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "openvidu-node-client": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/openvidu-node-client/-/openvidu-node-client-2.10.0.tgz", - "integrity": "sha512-j/vD4ZvbyRSVJPVY71s+NMpAvsMM4UaCgf/NDkcFWdyAq15s7KPAptQPaAy7eKEZD9u9xvOZzaJCSHsdg9iAuQ==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/openvidu-node-client/-/openvidu-node-client-2.11.0.tgz", + "integrity": "sha512-Mlv2c2nv0wTOWaazRPSepy3DZHnt/DtBDoFCOajCxDpuMbMjD+HayqLQOAg6KOlkOcAsEdt1NMmhkhtE188UyQ==", "requires": { "axios": "0.19.0", "buffer": "5.2.1" diff --git a/openvidu-mvc-node/package.json b/openvidu-mvc-node/package.json index dfa727639..2ee289806 100644 --- a/openvidu-mvc-node/package.json +++ b/openvidu-mvc-node/package.json @@ -1,6 +1,6 @@ { "name": "openvidu-mvc-node", - "version": "2.10.0", + "version": "2.11.0", "description": "", "main": "server.js", "scripts": { @@ -21,6 +21,6 @@ "ejs": "2.6.1", "express": "4.16.4", "express-session": "1.16.1", - "openvidu-node-client": "2.10.0" + "openvidu-node-client": "2.11.0" } } diff --git a/openvidu-mvc-node/public/openvidu-browser-2.10.0.js b/openvidu-mvc-node/public/openvidu-browser-2.10.0.js deleted file mode 100644 index c2d3bcd8c..000000000 --- a/openvidu-mvc-node/public/openvidu-browser-2.10.0.js +++ /dev/null @@ -1,8566 +0,0 @@ -(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 1) - 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('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (!events) - return []; - - var evlistener = events[type]; - if (!evlistener) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],2:[function(require,module,exports){ -/* jshint node: true */ -'use strict'; - -var normalice = require('normalice'); - -/** - # freeice - - The `freeice` module is a simple way of getting random STUN or TURN server - for your WebRTC application. The list of servers (just STUN at this stage) - were sourced from this [gist](https://gist.github.com/zziuni/3741933). - - ## Example Use - - The following demonstrates how you can use `freeice` with - [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): - - <<< examples/quickconnect.js - - As the `freeice` module generates ice servers in a list compliant with the - WebRTC spec you will be able to use it with raw `RTCPeerConnection` - constructors and other WebRTC libraries. - - ## Hey, don't use my STUN/TURN server! - - If for some reason your free STUN or TURN server ends up in the - list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or - [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) - that is used in this module, you can feel - free to open an issue on this repository and those servers will be removed - within 24 hours (or sooner). This is the quickest and probably the most - polite way to have something removed (and provides us some visibility - if someone opens a pull request requesting that a server is added). - - ## Please add my server! - - If you have a server that you wish to add to the list, that's awesome! I'm - sure I speak on behalf of a whole pile of WebRTC developers who say thanks. - To get it into the list, feel free to either open a pull request or if you - find that process a bit daunting then just create an issue requesting - the addition of the server (make sure you provide all the details, and if - you have a Terms of Service then including that in the PR/issue would be - awesome). - - ## I know of a free server, can I add it? - - Sure, if you do your homework and make sure it is ok to use (I'm currently - in the process of reviewing the terms of those STUN servers included from - the original list). If it's ok to go, then please see the previous entry - for how to add it. - - ## Current List of Servers - - * current as at the time of last `README.md` file generation - - ### STUN - - <<< stun.json - - ### TURN - - <<< turn.json - -**/ - -var freeice = function(opts) { - // if a list of servers has been provided, then use it instead of defaults - var servers = { - stun: (opts || {}).stun || require('./stun.json'), - turn: (opts || {}).turn || require('./turn.json') - }; - - var stunCount = (opts || {}).stunCount || 2; - var turnCount = (opts || {}).turnCount || 0; - var selected; - - function getServers(type, count) { - var out = []; - var input = [].concat(servers[type]); - var idx; - - while (input.length && out.length < count) { - idx = (Math.random() * input.length) | 0; - out = out.concat(input.splice(idx, 1)); - } - - return out.map(function(url) { - //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up - if ((typeof url !== 'string') && (! (url instanceof String))) { - return url; - } else { - return normalice(type + ':' + url); - } - }); - } - - // add stun servers - selected = [].concat(getServers('stun', stunCount)); - - if (turnCount) { - selected = selected.concat(getServers('turn', turnCount)); - } - - return selected; -}; - -module.exports = freeice; -},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ -module.exports=[ - "stun.l.google.com:19302", - "stun1.l.google.com:19302", - "stun2.l.google.com:19302", - "stun3.l.google.com:19302", - "stun4.l.google.com:19302", - "stun.ekiga.net", - "stun.ideasip.com", - "stun.schlund.de", - "stun.stunprotocol.org:3478", - "stun.voiparound.com", - "stun.voipbuster.com", - "stun.voipstunt.com", - "stun.voxgratia.org" -] - -},{}],4:[function(require,module,exports){ -module.exports=[] - -},{}],5:[function(require,module,exports){ -var WildEmitter = require('wildemitter'); - -function getMaxVolume (analyser, fftBins) { - var maxVolume = -Infinity; - analyser.getFloatFrequencyData(fftBins); - - for(var i=4, ii=fftBins.length; i < ii; i++) { - if (fftBins[i] > maxVolume && fftBins[i] < 0) { - maxVolume = fftBins[i]; - } - }; - - return maxVolume; -} - - -var audioContextType; -if (typeof window !== 'undefined') { - audioContextType = window.AudioContext || window.webkitAudioContext; -} -// use a single audio context due to hardware limits -var audioContext = null; -module.exports = function(stream, options) { - var harker = new WildEmitter(); - - // make it not break in non-supported browsers - if (!audioContextType) return harker; - - //Config - var options = options || {}, - smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), - threshold = options.threshold, - play = options.play, - history = options.history || 10, - running = true; - - // Ensure that just a single AudioContext is internally created - audioContext = options.audioContext || audioContext || new audioContextType(); - - var sourceNode, fftBins, analyser; - - analyser = audioContext.createAnalyser(); - analyser.fftSize = 512; - analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.frequencyBinCount); - - if (stream.jquery) stream = stream[0]; - if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { - //Audio Tag - sourceNode = audioContext.createMediaElementSource(stream); - if (typeof play === 'undefined') play = true; - threshold = threshold || -50; - } else { - //WebRTC Stream - sourceNode = audioContext.createMediaStreamSource(stream); - threshold = threshold || -50; - } - - sourceNode.connect(analyser); - if (play) analyser.connect(audioContext.destination); - - harker.speaking = false; - - harker.suspend = function() { - return audioContext.suspend(); - } - harker.resume = function() { - return audioContext.resume(); - } - Object.defineProperty(harker, 'state', { get: function() { - return audioContext.state; - }}); - audioContext.onstatechange = function() { - harker.emit('state_change', audioContext.state); - } - - harker.setThreshold = function(t) { - threshold = t; - }; - - harker.setInterval = function(i) { - interval = i; - }; - - harker.stop = function() { - running = false; - harker.emit('volume_change', -100, threshold); - if (harker.speaking) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - analyser.disconnect(); - sourceNode.disconnect(); - }; - harker.speakingHistory = []; - for (var i = 0; i < history; i++) { - harker.speakingHistory.push(0); - } - - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } - } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); - - looper(); - }, interval); - }; - looper(); - - return harker; -} - -},{"wildemitter":14}],6:[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 - } -} - -},{}],7:[function(require,module,exports){ -/** - # normalice - - Normalize an ice server configuration object (or plain old string) into a format - that is usable in all browsers supporting WebRTC. Primarily this module is designed - to help with the transition of the `url` attribute of the configuration object to - the `urls` attribute. - - ## Example Usage - - <<< examples/simple.js - -**/ - -var protocols = [ - 'stun:', - 'turn:' -]; - -module.exports = function(input) { - var url = (input || {}).url || input; - var protocol; - var parts; - var output = {}; - - // if we don't have a string url, then allow the input to passthrough - if (typeof url != 'string' && (! (url instanceof String))) { - return input; - } - - // trim the url string, and convert to an array - url = url.trim(); - - // if the protocol is not known, then passthrough - protocol = protocols[protocols.indexOf(url.slice(0, 5))]; - if (! protocol) { - return input; - } - - // now let's attack the remaining url parts - url = url.slice(5); - parts = url.split('@'); - - output.username = input.username; - output.credential = input.credential; - // if we have an authentication part, then set the credentials - if (parts.length > 1) { - url = parts[1]; - parts = parts[0].split(':'); - - // add the output credential and username - output.username = parts[0]; - output.credential = (input || {}).credential || parts[1] || ''; - } - - output.url = protocol + url; - output.urls = [ output.url ]; - - return output; -}; - -},{}],8:[function(require,module,exports){ -(function (global){ -/*! - * Platform.js - * Copyright 2014-2018 Benjamin Tan - * Copyright 2011-2013 John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object. */ - var oldRoot = root; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Regular expression to detect Opera. */ - var reOpera = /\bOpera/; - - /** Possible global object. */ - var thisBinding = this; - - /** Used for native method references. */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values. */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // Platform tokens are defined at: - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '10.0': '10', - '6.4': '10 Technical Preview', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // Detect Windows version from platform tokens. - if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && - (data = data[/[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // Correct character case and cleanup string. - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object. */ - var context = root; - - /** Used to flag when a custom context is provided. */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // Juggle arguments. - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object. */ - var nav = context.navigator || {}; - - /** Browser user agent string. */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope]. */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome. */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts. */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environments. */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino. */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha. */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta. */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object. */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based). - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]`. */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime. */ - var data; - - /** The CPU architecture. */ - var arch = ua; - - /** Platform description array. */ - var description = []; - - /** Platform alpha/beta indicator. */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform. */ - var useFeatures = ua == userAgent; - - /** The browser/environment version. */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important). */ - var layout = getLayout([ - { 'label': 'EdgeHTML', 'pattern': 'Edge' }, - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important). */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Electron', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, - 'Midori', - 'Nook Browser', - 'PaleMoon', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'Sunrise', - 'Swiftfox', - 'Waterfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important). */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, - { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, - { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, - { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, - { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nexus', - 'Nook', - 'PlayBook', - 'PlayStation Vita', - 'PlayStation', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers. */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Archos': {}, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1, 'Nexus': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable operating systems (order is important). */ - var os = getOS([ - 'Windows Phone', - 'Android', - 'CentOS', - { 'label': 'Chrome OS', 'pattern': 'CrOS' }, - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'OpenBSD', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Tizen', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // Lookup the manufacturer by product or scan the UA for the manufacturer. - return result || ( - value[product] || - value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // Split by forward slash and append product version if needed. - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // Correct character case and cleanup string. - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // Convert layout to an array so we can add extra details. - layout && (layout = [layout]); - - // Detect product names that contain their manufacturer's name. - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // Clean up Google TV. - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // Detect simulators. - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // Detect IE Mobile 11. - if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { - data = parse(ua.replace(/like iPhone OS/, '')); - manufacturer = data.manufacturer; - product = data.product; - } - // Detect iOS. - else if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // Detect Kubuntu. - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // Detect Android browsers. - else if ((manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || - (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // Detect Silk desktop/accelerated modes. - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // Detect PaleMoon identifying as Firefox. - else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { - description.push('identifying as Firefox ' + data[1]); - } - // Detect Firefox OS and products running Firefox. - else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { - os || (os = 'Firefox OS'); - product || (product = data[1]); - } - // Detect false positives for Firefox/Safari. - else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // Escape the `/` for Firefox 1. - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // Clear name of false positives. - name = null; - } - // Reassign a generic name. - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // Add Chrome version to description for Electron. - else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { - description.push('Chromium ' + data); - } - // Detect non-Opera (Presto-based) versions (order is important). - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // Detect stubborn layout engines. - if ((data = - layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || - layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' - )) { - layout = [data]; - } - // Detect Windows Phone 7 desktop mode. - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // Detect Windows Phone 8.x desktop mode. - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8.x'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // Detect IE 11 identifying as other browsers. - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - version = data[1]; - } - // Leverage environment features. - if (useFeatures) { - // Detect server-side environments. - // Rhino has a global function while others have a global object. - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (rhino) { - try { - version = context.require('ringo/engine').version.join('.'); - name = 'RingoJS'; - } catch(e) { - if ((data = context.system) && data.global.system == context.system) { - name = 'Narwhal'; - os || (os = data[0].os || null); - } - } - if (!name) { - name = 'Rhino'; - } - } - else if ( - typeof context.process == 'object' && !context.process.browser && - (data = context.process) - ) { - if (typeof data.versions == 'object') { - if (typeof data.versions.electron == 'string') { - description.push('Node ' + data.versions.node); - name = 'Electron'; - version = data.versions.electron; - } else if (typeof data.versions.nw == 'string') { - description.push('Chromium ' + version, 'Node ' + data.versions.node); - name = 'NW.js'; - version = data.versions.nw; - } - } - if (!name) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version); - version = version ? version[0] : null; - } - } - } - // Detect Adobe AIR. - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // Detect PhantomJS. - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // Detect IE compatibility modes. - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // We're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode. - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - // Detect IE 11 masking as other browsers. - else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { - description.push('masking as ' + name + ' ' + version); - name = 'IE'; - version = '11.0'; - layout = ['Trident']; - os = 'Windows'; - } - os = os && format(os); - } - // Detect prerelease phases. - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // Detect Firefox Mobile. - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // Obscure Maxthon's unreliable version. - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // Detect Xbox 360 and Xbox One. - else if (/\bXbox\b/i.test(product)) { - if (product == 'Xbox 360') { - os = null; - } - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // Add mobile postfix. - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // Detect IE platform preview. - else if (name == 'IE' && useFeatures) { - try { - if (context.external === null) { - description.unshift('platform preview'); - } - } catch(e) { - description.unshift('embedded'); - } - } - // Detect BlackBerry OS version. - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // Detect Opera identifying/masking itself as another browser. - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - // When "identifying", the UA contains both Opera and the other browser's name. - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // When "masking", the UA contains only the other browser's name. - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // Detect WebKit Nightly and approximate Chrome/Safari versions. - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // Correct build number for numeric comparison. - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // Nightly builds are postfixed with a "+". - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // Clear incorrect browser versions. - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // Use the full Chrome version when available. - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // Detect Blink layout engine. - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { - layout = ['Blink']; - } - // Detect JavaScriptCore. - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // Add the postfix of ".x" or "+" for approximate versions. - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // Obscure version for some Safari 1-2 releases. - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // Detect Opera desktop modes. - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // Detect Chrome desktop mode. - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // Strip incorrect OS versions. - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // Add layout engine. - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { - // Don't add layout details to description if they are falsey. - (data = layout[layout.length - 1]) && description.push(data); - } - // Combine contextual information. - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // Append manufacturer to description. - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // Append product to description. - if (product) { - description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); - } - // Parse the OS into an object. - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // Add browser/OS architecture. - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - // Chrome 39 and above on OS X is always 64-bit. - else if ( - os && /^OS X/.test(os.family) && - name == 'Chrome' && parseFloat(version) >= 39 - ) { - os.architecture = 64; - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * The list of common layout engines include: - * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * The list of manufacturers include: - * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", - * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", - * "Nokia", "Samsung" and "Sony" - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * The list of common browser names include: - * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", - * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", - * "Opera Mini" and "Opera" - * - * Mobile versions of some browsers have "Mobile" appended to their name: - * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * The list of common products include: - * - * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", - * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // Export platform. - var platform = parse(); - - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose platform on the global object to prevent errors when platform is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - root.platform = platform; - - // Define as an anonymous module so platform can be aliased through path mapping. - define(function() { - return platform; - }); - } - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { - // Export for CommonJS support. - forOwn(platform, function(value, key) { - freeExports[key] = value; - }); - } - else { - // Export to the global object. - root.platform = platform; - } -}.call(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],9:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - -},{}],11:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],12:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ -/* -WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based -on @visionmedia's Emitter from UI Kit. - -Why? I wanted it standalone. - -I also wanted support for wildcard emitters like this: - -emitter.on('*', function (eventName, other, event, payloads) { - -}); - -emitter.on('somenamespace*', function (eventName, payloads) { - -}); - -Please note that callbacks triggered by wildcard registered events also get -the event name as the first argument. -*/ - -module.exports = WildEmitter; - -function WildEmitter() { } - -WildEmitter.mixin = function (constructor) { - var prototype = constructor.prototype || constructor; - - prototype.isWildEmitter= true; - - // Listen on the given `event` with `fn`. Store a group name if present. - prototype.on = function (event, groupName, fn) { - this.callbacks = this.callbacks || {}; - var hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - func._groupName = group; - (this.callbacks[event] = this.callbacks[event] || []).push(func); - return this; - }; - - // Adds an `event` listener that will be invoked a single - // time then automatically removed. - prototype.once = function (event, groupName, fn) { - var self = this, - hasGroup = (arguments.length === 3), - group = hasGroup ? arguments[1] : undefined, - func = hasGroup ? arguments[2] : arguments[1]; - function on() { - self.off(event, on); - func.apply(this, arguments); - } - this.on(event, group, on); - return this; - }; - - // Unbinds an entire group - prototype.releaseGroup = function (groupName) { - this.callbacks = this.callbacks || {}; - var item, i, len, handlers; - for (item in this.callbacks) { - handlers = this.callbacks[item]; - for (i = 0, len = handlers.length; i < len; i++) { - if (handlers[i]._groupName === groupName) { - //console.log('removing'); - // remove it and shorten the array we're looping through - handlers.splice(i, 1); - i--; - len--; - } - } - } - return this; - }; - - // Remove the given callback for `event` or all - // registered callbacks. - prototype.off = function (event, fn) { - this.callbacks = this.callbacks || {}; - var callbacks = this.callbacks[event], - i; - - if (!callbacks) return this; - - // remove all handlers - if (arguments.length === 1) { - delete this.callbacks[event]; - return this; - } - - // remove specific handler - i = callbacks.indexOf(fn); - callbacks.splice(i, 1); - if (callbacks.length === 0) { - delete this.callbacks[event]; - } - return this; - }; - - /// Emit `event` with the given args. - // also calls any `*` handlers - prototype.emit = function (event) { - this.callbacks = this.callbacks || {}; - var args = [].slice.call(arguments, 1), - callbacks = this.callbacks[event], - specialCallbacks = this.getWildcardCallbacks(event), - i, - len, - item, - listeners; - - if (callbacks) { - listeners = callbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, args); - } - } - - if (specialCallbacks) { - len = specialCallbacks.length; - listeners = specialCallbacks.slice(); - for (i = 0, len = listeners.length; i < len; ++i) { - if (!listeners[i]) { - break; - } - listeners[i].apply(this, [event].concat(args)); - } - } - - return this; - }; - - // Helper for for finding special wildcard event handlers that match the event - prototype.getWildcardCallbacks = function (eventName) { - this.callbacks = this.callbacks || {}; - var item, - split, - result = []; - - for (item in this.callbacks) { - split = item.split('*'); - if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { - result = result.concat(this.callbacks[item]); - } - } - return result; - }; - -}; - -WildEmitter.mixin(WildEmitter); - -},{}],15:[function(require,module,exports){ -/*! - * EventEmitter v5.2.6 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - https://oli.me.uk/ - * @preserve - */ - -;(function (exports) { - 'use strict'; - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - function isValidListener (listener) { - if (typeof listener === 'function' || listener instanceof RegExp) { - return true - } else if (listener && typeof listener === 'object') { - return isValidListener(listener.listener) - } else { - return false - } - } - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - if (!isValidListener(listener)) { - throw new TypeError('listener must be a function'); - } - - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listenersMap = this.getListenersAsObject(evt); - var listeners; - var listener; - var i; - var key; - var response; - - for (key in listenersMap) { - if (listenersMap.hasOwnProperty(key)) { - listeners = listenersMap[key].slice(0); - - for (i = 0; i < listeners.length; i++) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define(function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}(typeof window !== 'undefined' ? window : this || {})); - -},{}],16:[function(require,module,exports){ -module.exports={ - "author": "OpenVidu", - "dependencies": { - "@types/node": "12.0.3", - "@types/platform": "1.3.2", - "freeice": "2.2.2", - "hark": "1.2.3", - "platform": "1.3.5", - "uuid": "3.3.2", - "wolfy87-eventemitter": "5.2.6" - }, - "description": "OpenVidu Browser", - "devDependencies": { - "browserify": "16.2.3", - "grunt": "1.0.4", - "grunt-autoprefixer": "3.0.4", - "grunt-cli": "1.3.2", - "grunt-contrib-copy": "1.0.0", - "grunt-contrib-sass": "1.0.0", - "grunt-contrib-uglify": "4.0.1", - "grunt-contrib-watch": "1.1.0", - "grunt-string-replace": "1.3.1", - "grunt-ts": "6.0.0-beta.22", - "tsify": "4.0.1", - "tslint": "5.16.0", - "typedoc": "0.14.2", - "typescript": "3.4.5", - "uglify-js": "3.5.15" - }, - "license": "Apache-2.0", - "main": "lib/index.js", - "name": "openvidu-browser", - "repository": { - "type": "git", - "url": "git://github.com/OpenVidu/openvidu" - }, - "scripts": { - "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", - "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", - "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", - "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "types": "lib/index.d.ts", - "version": "2.10.0" -} - -},{}],17:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenVidu_1 = require("./OpenVidu/OpenVidu"); -if (window) { - window['OpenVidu'] = OpenVidu_1.OpenVidu; -} - -},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Stream_1 = require("./Stream"); -var Connection = (function () { - function Connection(session, opts) { - this.session = session; - this.disposed = false; - var msg = "'Connection' created "; - if (!!opts) { - msg += "(remote) with 'connectionId' [" + opts.id + ']'; - this.options = opts; - this.connectionId = opts.id; - this.creationTime = opts.createdAt; - if (opts.metadata) { - this.data = opts.metadata; - } - if (opts.streams) { - this.initRemoteStreams(opts.streams); - } - } - else { - msg += '(local)'; - } - console.info(msg); - } - Connection.prototype.sendIceCandidate = function (candidate) { - console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + - this.connectionId, candidate); - this.session.openvidu.sendRequest('onIceCandidate', { - endpointName: this.connectionId, - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }, function (error, response) { - if (error) { - console.error('Error sending ICE candidate: ' - + JSON.stringify(error)); - } - }); - }; - Connection.prototype.initRemoteStreams = function (options) { - var _this = this; - options.forEach(function (opts) { - var streamOptions = { - id: opts.id, - createdAt: opts.createdAt, - connection: _this, - hasAudio: opts.hasAudio, - hasVideo: opts.hasVideo, - audioActive: opts.audioActive, - videoActive: opts.videoActive, - typeOfVideo: opts.typeOfVideo, - frameRate: opts.frameRate, - videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, - filter: !!opts.filter ? opts.filter : undefined - }; - var stream = new Stream_1.Stream(_this.session, streamOptions); - _this.addStream(stream); - }); - console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); - }; - Connection.prototype.addStream = function (stream) { - stream.connection = this; - this.stream = stream; - }; - Connection.prototype.removeStream = function (streamId) { - delete this.stream; - }; - Connection.prototype.dispose = function () { - if (!!this.stream) { - delete this.stream; - } - this.disposed = true; - }; - return Connection; -}()); -exports.Connection = Connection; - -},{"./Stream":24}],19:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var Filter = (function () { - function Filter(type, options) { - this.handlers = {}; - this.type = type; - this.options = options; - } - Filter.prototype.execMethod = function (method, params) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Executing filter method to stream ' + _this.stream.streamId); - var stringParams; - if (typeof params !== 'string') { - try { - stringParams = JSON.stringify(params); - } - catch (error) { - var errorMsg = "'params' property must be a JSON formatted object"; - console.error(errorMsg); - reject(errorMsg); - } - } - else { - stringParams = params; - } - _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { - if (error) { - console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); - } - else { - reject(error); - } - } - else { - console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); - var oldValue = Object.assign({}, _this.stream.filter); - _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; - _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); - resolve(); - } - }); - }); - }; - Filter.prototype.addEventListener = function (eventType, handler) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - _this.handlers[eventType] = handler; - console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - Filter.prototype.removeEventListener = function (eventType) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); - _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { - if (error) { - console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); - } - else { - reject(error); - } - } - else { - delete _this.handlers[eventType]; - console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); - resolve(); - } - }); - }); - }; - return Filter; -}()); -exports.Filter = Filter; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); -var platform = require("platform"); -var LocalRecorder = (function () { - function LocalRecorder(stream) { - this.stream = stream; - this.chunks = []; - this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; - this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; - this.state = LocalRecorderState_1.LocalRecorderState.READY; - } - LocalRecorder.prototype.record = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (typeof MediaRecorder === 'undefined') { - console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); - throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); - } - if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { - throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); - } - console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); - if (typeof MediaRecorder.isTypeSupported === 'function') { - var options = void 0; - if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { - options = { mimeType: 'video/webm;codecs=vp9' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { - options = { mimeType: 'video/webm;codecs=h264' }; - } - else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { - options = { mimeType: 'video/webm;codecs=vp8' }; - } - console.log('Using mimeType ' + options.mimeType); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); - } - else { - console.warn('isTypeSupported is not supported, using default codecs for browser'); - _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); - } - _this.mediaRecorder.start(10); - } - catch (err) { - reject(err); - } - _this.mediaRecorder.ondataavailable = function (e) { - _this.chunks.push(e.data); - }; - _this.mediaRecorder.onerror = function (e) { - console.error('MediaRecorder error: ', e); - }; - _this.mediaRecorder.onstart = function () { - console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - }; - _this.mediaRecorder.onpause = function () { - console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onresume = function () { - console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); - }; - _this.mediaRecorder.onwarning = function (e) { - console.log('MediaRecorder warning: ' + e); - }; - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - resolve(); - }); - }; - LocalRecorder.prototype.stop = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); - } - _this.mediaRecorder.onstop = function () { - _this.onStopDefault(); - resolve(); - }; - _this.mediaRecorder.stop(); - } - catch (e) { - reject(e); - } - }); - }; - LocalRecorder.prototype.pause = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { - reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); - } - _this.mediaRecorder.pause(); - _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.resume = function () { - var _this = this; - return new Promise(function (resolve, reject) { - try { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { - throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); - } - _this.mediaRecorder.resume(); - _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; - } - catch (error) { - reject(error); - } - }); - }; - LocalRecorder.prototype.preview = function (parentElement) { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - this.videoPreview = document.createElement('video'); - this.videoPreview.id = this.id; - this.videoPreview.autoplay = true; - if (platform.name === 'Safari') { - this.videoPreview.setAttribute('playsinline', 'true'); - } - if (typeof parentElement === 'string') { - var parentElementDom = document.getElementById(parentElement); - if (parentElementDom) { - this.videoPreview = parentElementDom.appendChild(this.videoPreview); - } - } - else { - this.videoPreview = parentElement.appendChild(this.videoPreview); - } - this.videoPreview.src = this.videoPreviewSrc; - return this.videoPreview; - }; - LocalRecorder.prototype.clean = function () { - var _this = this; - var f = function () { - delete _this.blob; - _this.chunks = []; - delete _this.mediaRecorder; - _this.state = LocalRecorderState_1.LocalRecorderState.READY; - }; - if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { - this.stop().then(function () { return f(); }).catch(function () { return f(); }); - } - else { - f(); - } - }; - LocalRecorder.prototype.download = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); - var url = window.URL.createObjectURL(this.blob); - a.href = url; - a.download = this.id + '.webm'; - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } - }; - LocalRecorder.prototype.getBlob = function () { - if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); - } - else { - return this.blob; - } - }; - LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_1 = new XMLHttpRequest(); - http_1.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_1.setRequestHeader(key, headers[key]); - } - } - http_1.onreadystatechange = function () { - if (http_1.readyState === 4) { - if (http_1.status.toString().charAt(0) === '2') { - resolve(http_1.responseText); - } - else { - reject(http_1.status); - } - } - }; - http_1.send(_this.blob); - } - }); - }; - LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { - reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); - } - else { - var http_2 = new XMLHttpRequest(); - http_2.open('POST', endpoint, true); - if (typeof headers === 'object') { - for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { - var key = _a[_i]; - http_2.setRequestHeader(key, headers[key]); - } - } - var sendable = new FormData(); - sendable.append('file', _this.blob, _this.id + '.webm'); - http_2.onreadystatechange = function () { - if (http_2.readyState === 4) { - if (http_2.status.toString().charAt(0) === '2') { - resolve(http_2.responseText); - } - else { - reject(http_2.status); - } - } - }; - http_2.send(sendable); - } - }); - }; - LocalRecorder.prototype.onStopDefault = function () { - console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); - this.blob = new Blob(this.chunks, { type: 'video/webm' }); - this.chunks = []; - this.videoPreviewSrc = window.URL.createObjectURL(this.blob); - this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; - }; - return LocalRecorder; -}()); -exports.LocalRecorder = LocalRecorder; - -},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorder_1 = require("./LocalRecorder"); -var Publisher_1 = require("./Publisher"); -var Session_1 = require("./Session"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); -var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); -var EventEmitter = require("wolfy87-eventemitter"); -var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); -var platform = require("platform"); -platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; -var packageJson = require('../../package.json'); -var OpenVidu = (function () { - function OpenVidu() { - var _this = this; - this.publishers = []; - this.secret = ''; - this.recorder = false; - this.advancedConfiguration = {}; - this.webrtcStatsInterval = 0; - this.ee = new EventEmitter(); - this.libraryVersion = packageJson.version; - console.info("'OpenVidu' initialized"); - console.info("openvidu-browser version: " + this.libraryVersion); - if (platform.os.family === 'iOS' || platform.os.family === 'Android') { - window.addEventListener('orientationchange', function () { - _this.publishers.forEach(function (publisher) { - if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { - var attempts_1 = 0; - var oldWidth_1 = publisher.stream.videoDimensions.width; - var oldHeight_1 = publisher.stream.videoDimensions.height; - var getNewVideoDimensions_1 = function () { - return new Promise(function (resolve, reject) { - if (platform['isIonicIos']) { - resolve({ - newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, - newHeight: publisher.stream.streamManager.videos[0].video.videoHeight - }); - } - else { - var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); - var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); - var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); - resolve({ newWidth: newWidth, newHeight: newHeight }); - } - }); - }; - var repeatUntilChange_1 = setInterval(function () { - getNewVideoDimensions_1().then(function (newDimensions) { - sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); - }); - }, 75); - var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { - attempts_1++; - if (attempts_1 > 10) { - clearTimeout(repeatUntilChange_1); - } - if (newWidth !== oldWidth || newHeight !== oldHeight) { - publisher.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.sendRequest('streamPropertyChanged', { - streamId: publisher.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(publisher.stream.videoDimensions), - reason: 'deviceRotated' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); - } - }); - clearTimeout(repeatUntilChange_1); - } - }; - } - }); - }); - } - } - OpenVidu.prototype.initSession = function () { - this.session = new Session_1.Session(this); - return this.session; - }; - OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { - var properties; - if (!!param2 && (typeof param2 !== 'function')) { - properties = param2; - properties = { - audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, - frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), - insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, - publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, - publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, - resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), - videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, - filter: properties.filter - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - mirror: true, - publishAudio: true, - publishVideo: true, - resolution: '640x480' - }; - } - var publisher = new Publisher_1.Publisher(targetElement, properties, this); - var completionHandler; - if (!!param2 && (typeof param2 === 'function')) { - completionHandler = param2; - } - else if (!!param3) { - completionHandler = param3; - } - publisher.initialize() - .then(function () { - if (completionHandler !== undefined) { - completionHandler(undefined); - } - publisher.emitEvent('accessAllowed', []); - }).catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - publisher.emitEvent('accessDenied', [error]); - }); - this.publishers.push(publisher); - return publisher; - }; - OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var publisher; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(publisher); - } - }; - if (!!properties) { - publisher = _this.initPublisher(targetElement, properties, callback); - } - else { - publisher = _this.initPublisher(targetElement, callback); - } - }); - }; - OpenVidu.prototype.initLocalRecorder = function (stream) { - return new LocalRecorder_1.LocalRecorder(stream); - }; - OpenVidu.prototype.checkSystemRequirements = function () { - var browser = platform.name; - var family = platform.os.family; - var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; - if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { - return 0; - } - if ((browser !== 'Safari') && - (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && - (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && - (browser !== 'Opera') && (browser !== 'Opera Mobile') && - (browser !== 'Android Browser') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.checkScreenSharingCapabilities = function () { - var browser = platform.name; - var family = platform.os.family; - if (family === 'iOS' || family === 'Android') { - return 0; - } - if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { - return 0; - } - else { - return 1; - } - }; - OpenVidu.prototype.getDevices = function () { - return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { - var devices = []; - deviceInfos.forEach(function (deviceInfo) { - if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { - devices.push({ - kind: deviceInfo.kind, - deviceId: deviceInfo.deviceId, - label: deviceInfo.label - }); - } - }); - resolve(devices); - }).catch(function (error) { - console.error('Error getting devices', error); - reject(error); - }); - }); - }; - OpenVidu.prototype.getUserMedia = function (options) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.generateMediaConstraints(options) - .then(function (constraints) { - navigator.mediaDevices.getUserMedia(constraints) - .then(function (mediaStream) { - resolve(mediaStream); - }) - .catch(function (error) { - var errorName; - var errorMessage = error.toString(); - if (!(options.videoSource === 'screen')) { - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; - } - reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - OpenVidu.prototype.enableProdMode = function () { - console.log = function () { }; - console.debug = function () { }; - console.info = function () { }; - console.warn = function () { }; - }; - OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { - this.advancedConfiguration = configuration; - }; - OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { - var _this = this; - return new Promise(function (resolve, reject) { - var audio, video; - if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { - audio = false; - } - else if (publisherProperties.audioSource === undefined) { - audio = true; - } - else { - audio = publisherProperties.audioSource; - } - if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { - video = false; - } - else { - video = { - height: { - ideal: 480 - }, - width: { - ideal: 640 - } - }; - } - var mediaConstraints = { - audio: audio, - video: video - }; - if (typeof mediaConstraints.audio === 'string') { - mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; - } - if (mediaConstraints.video) { - if (!!publisherProperties.resolution) { - var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); - var width = Number(widthAndHeight[0]); - var height = Number(widthAndHeight[1]); - mediaConstraints.video.width.ideal = width; - mediaConstraints.video.height.ideal = height; - } - if (!!publisherProperties.frameRate) { - mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; - } - if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { - if (publisherProperties.videoSource === 'screen' || - (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || - (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { - if (!_this.checkScreenSharingCapabilities()) { - var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); - console.error(error); - reject(error); - } - else { - if (platform.name === 'Electron') { - var prefix = "screen:"; - var videoSourceString = publisherProperties.videoSource; - var electronScreenId = videoSourceString.substr(videoSourceString.lastIndexOf(prefix) + prefix.length); - mediaConstraints['video'] = { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: electronScreenId - } - }; - resolve(mediaConstraints); - } - else { - if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { - screenSharing.getScreenConstraints(function (error, screenConstraints) { - if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { - if (error === 'permission-denied' || error === 'PermissionDeniedError') { - var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_1); - reject(error_1); - } - else { - var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); - screenSharing.getChromeExtensionStatus(extensionId, function (status) { - if (status === 'installed-disabled') { - var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_2); - reject(error_2); - } - if (status === 'not-installed') { - var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); - console.error(error_3); - reject(error_3); - } - }); - } - } - else { - mediaConstraints.video = screenConstraints; - resolve(mediaConstraints); - } - }); - } - else { - if (navigator.mediaDevices['getDisplayMedia']) { - resolve(mediaConstraints); - } - else { - var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; - screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { - if (!!error) { - if (error === 'not-installed') { - var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : - 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; - var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); - console.error(error_4); - reject(error_4); - } - else if (error === 'installed-disabled') { - var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); - console.error(error_5); - reject(error_5); - } - else if (error === 'permission-denied') { - var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error_6); - reject(error_6); - } - } - else { - mediaConstraints.video = screenConstraints.video; - resolve(mediaConstraints); - } - }); - } - } - publisherProperties.videoSource = 'screen'; - } - } - } - else { - mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - } - else { - resolve(mediaConstraints); - } - }); - }; - OpenVidu.prototype.startWs = function (onConnectSucces) { - var config = { - heartbeat: 5000, - sendCloseMessage: false, - ws: { - uri: this.wsUri, - useSockJS: false, - onconnected: onConnectSucces, - ondisconnect: this.disconnectCallback.bind(this), - onreconnecting: this.reconnectingCallback.bind(this), - onreconnected: this.reconnectedCallback.bind(this) - }, - rpc: { - requestTimeout: 10000, - participantJoined: this.session.onParticipantJoined.bind(this.session), - participantPublished: this.session.onParticipantPublished.bind(this.session), - participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), - participantLeft: this.session.onParticipantLeft.bind(this.session), - participantEvicted: this.session.onParticipantEvicted.bind(this.session), - recordingStarted: this.session.onRecordingStarted.bind(this.session), - recordingStopped: this.session.onRecordingStopped.bind(this.session), - sendMessage: this.session.onNewMessage.bind(this.session), - streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), - filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), - iceCandidate: this.session.recvIceCandidate.bind(this.session), - mediaError: this.session.onMediaError.bind(this.session) - } - }; - this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); - }; - OpenVidu.prototype.closeWs = function () { - this.jsonRpcClient.close(4102, "Connection closed by client"); - }; - OpenVidu.prototype.sendRequest = function (method, params, callback) { - if (params && params instanceof Function) { - callback = params; - params = {}; - } - console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); - this.jsonRpcClient.send(method, params, callback); - }; - OpenVidu.prototype.getWsUri = function () { - return this.wsUri; - }; - OpenVidu.prototype.getSecret = function () { - return this.secret; - }; - OpenVidu.prototype.getRecorder = function () { - return this.recorder; - }; - OpenVidu.prototype.disconnectCallback = function () { - console.warn('Websocket connection lost'); - if (this.isRoomAvailable()) { - this.session.onLostConnection('networkDisconnect'); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectingCallback = function () { - console.warn('Websocket connection lost (reconnecting)'); - if (!this.isRoomAvailable()) { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.reconnectedCallback = function () { - var _this = this; - console.warn('Websocket reconnected'); - if (this.isRoomAvailable()) { - this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { - if (!!error) { - console.error(error); - _this.session.onLostConnection("networkDisconnect"); - _this.jsonRpcClient.close(4101, "Reconnection fault"); - } - else { - _this.jsonRpcClient.resetPing(); - _this.session.onRecoveredConnection(); - } - }); - } - else { - alert('Connection error. Please reload page.'); - } - }; - OpenVidu.prototype.isRoomAvailable = function () { - if (this.session !== undefined && this.session instanceof Session_1.Session) { - return true; - } - else { - console.warn('Session instance not found'); - return false; - } - }; - return OpenVidu; -}()); -exports.OpenVidu = OpenVidu; - -},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Session_1 = require("./Session"); -var Stream_1 = require("./Stream"); -var StreamManager_1 = require("./StreamManager"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var platform = require("platform"); -var Publisher = (function (_super) { - __extends(Publisher, _super); - function Publisher(targEl, properties, openvidu) { - var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; - _this.accessAllowed = false; - _this.isSubscribedToRemote = false; - _this.accessDenied = false; - _this.properties = properties; - _this.openvidu = openvidu; - _this.stream.ee.on('local-stream-destroyed', function (reason) { - _this.stream.isLocalStreamPublished = false; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); - _this.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - }); - return _this; - } - Publisher.prototype.publishAudio = function (value) { - var _this = this; - if (this.stream.audioActive !== value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'audioActive', - newValue: value, - reason: 'publishAudio' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); - } - }); - } - this.stream.audioActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); - } - }; - Publisher.prototype.publishVideo = function (value) { - var _this = this; - if (this.stream.videoActive !== value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - if (!!this.session && !!this.stream.streamId) { - this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: this.stream.streamId, - property: 'videoActive', - newValue: value, - reason: 'publishVideo' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); - } - }); - } - this.stream.videoActive = value; - console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); - } - }; - Publisher.prototype.subscribeToRemote = function (value) { - value = (value !== undefined) ? value : true; - this.isSubscribedToRemote = value; - this.stream.subscribeToMyRemote(value); - }; - Publisher.prototype.on = function (type, handler) { - var _this = this; - _super.prototype.on.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.on('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.once = function (type, handler) { - var _this = this; - _super.prototype.once.call(this, type, handler); - if (type === 'streamCreated') { - if (!!this.stream && this.stream.isLocalStreamPublished) { - this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); - } - else { - this.stream.ee.once('stream-created-by-publisher', function () { - _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); - }); - } - } - if (type === 'remoteVideoPlaying') { - if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); - } - } - if (type === 'accessAllowed') { - if (this.accessAllowed) { - this.emitEvent('accessAllowed', []); - } - } - if (type === 'accessDenied') { - if (this.accessDenied) { - this.emitEvent('accessDenied', []); - } - } - return this; - }; - Publisher.prototype.initialize = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var constraints = {}; - var constraintsAux = {}; - var timeForDialogEvent = 1250; - var startTime; - var errorCallback = function (openViduError) { - _this.accessDenied = true; - _this.accessAllowed = false; - reject(openViduError); - }; - var successCallback = function (mediaStream) { - _this.accessAllowed = true; - _this.accessDenied = false; - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); - mediaStream.addTrack(_this.properties.audioSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); - mediaStream.addTrack(_this.properties.videoSource); - } - if (!!mediaStream.getAudioTracks()[0]) { - var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; - mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!mediaStream.getVideoTracks()[0]) { - var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; - mediaStream.getVideoTracks()[0].enabled = enabled; - } - _this.videoReference = document.createElement('video'); - if (platform.name === 'Safari') { - _this.videoReference.setAttribute('playsinline', 'true'); - } - _this.stream.setMediaStream(mediaStream); - if (!!_this.firstVideoElement) { - _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); - } - _this.videoReference.srcObject = mediaStream; - if (!_this.stream.displayMyRemote()) { - _this.stream.updateMediaStreamInVideos(); - } - delete _this.firstVideoElement; - if (_this.stream.isSendVideo()) { - if (!_this.stream.isSendScreen()) { - if (platform['isIonicIos'] || platform.name === 'Safari') { - _this.videoReference.style.display = 'none'; - document.body.appendChild(_this.videoReference); - var videoDimensionsSet_1 = function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - document.body.removeChild(_this.videoReference); - }; - var interval_1; - _this.videoReference.addEventListener('loadedmetadata', function () { - if (_this.videoReference.videoWidth === 0) { - interval_1 = setInterval(function () { - if (_this.videoReference.videoWidth !== 0) { - clearInterval(interval_1); - videoDimensionsSet_1(); - } - }, 40); - } - else { - videoDimensionsSet_1(); - } - }); - } - else { - var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; - if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { - _this.stream.videoDimensions = { - width: height || 0, - height: width || 0 - }; - } - else { - _this.stream.videoDimensions = { - width: width || 0, - height: height || 0 - }; - } - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - } - else { - _this.videoReference.addEventListener('loadedmetadata', function () { - _this.stream.videoDimensions = { - width: _this.videoReference.videoWidth, - height: _this.videoReference.videoHeight - }; - _this.screenShareResizeInterval = setInterval(function () { - var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); - var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; - var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; - if (_this.stream.isLocalStreamPublished && - (newWidth !== _this.stream.videoDimensions.width || - newHeight !== _this.stream.videoDimensions.height)) { - var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; - _this.stream.videoDimensions = { - width: newWidth || 0, - height: newHeight || 0 - }; - _this.session.openvidu.sendRequest('streamPropertyChanged', { - streamId: _this.stream.streamId, - property: 'videoDimensions', - newValue: JSON.stringify(_this.stream.videoDimensions), - reason: 'screenResized' - }, function (error, response) { - if (error) { - console.error("Error sending 'streamPropertyChanged' event", error); - } - else { - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); - } - }); - } - }, 500); - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - }); - } - } - else { - _this.stream.isLocalStreamReadyToPublish = true; - _this.stream.ee.emitEvent('stream-ready-to-publish', []); - } - resolve(); - }; - var getMediaSuccess = function (mediaStream, definedAudioConstraint) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { - constraintsAux.audio = definedAudioConstraint; - constraintsAux.video = false; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (audioOnlyStream) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); - successCallback(mediaStream); - }) - .catch(function (error) { - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'notallowederror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }); - } - else { - successCallback(mediaStream); - } - }; - var getMediaError = function (error) { - console.error(error); - _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); - if (error.name === 'Error') { - error.name = error.constructor.name; - } - var errorName, errorMessage; - switch (error.name.toLowerCase()) { - case 'notfounderror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'notallowederror': - errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - case 'overconstrainederror': - navigator.mediaDevices.getUserMedia({ - audio: false, - video: constraints.video - }) - .then(function (mediaStream) { - mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; - errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }).catch(function (e) { - if (error.constraint.toLowerCase() === 'deviceid') { - errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; - errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; - } - else { - errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; - errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; - } - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - }); - break; - case 'aborterror': - case 'notreadableerror': - errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - default: - errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; - errorMessage = error.toString(); - errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); - break; - } - }; - if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) - || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { - var mediaStream = new MediaStream(); - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.videoSource); - } - if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { - mediaStream.addTrack(_this.properties.audioSource); - } - successCallback(mediaStream); - return; - } - _this.openvidu.generateMediaConstraints(_this.properties) - .then(function (myConstraints) { - constraints = myConstraints; - var outboundStreamOptions = { - mediaConstraints: constraints, - publisherProperties: _this.properties - }; - _this.stream.setOutboundStreamOptions(outboundStreamOptions); - if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { - var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); - constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; - constraintsAux.video = constraints.video; - startTime = Date.now(); - _this.setPermissionDialogTimer(timeForDialogEvent); - if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { - navigator.mediaDevices['getDisplayMedia']({ video: true }) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - else { - navigator.mediaDevices.getUserMedia(constraintsAux) - .then(function (mediaStream) { - getMediaSuccess(mediaStream, definedAudioConstraint_1); - }) - .catch(function (error) { - getMediaError(error); - }); - } - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); - } - }) - .catch(function (error) { - errorCallback(error); - }); - }); - }; - Publisher.prototype.reestablishStreamPlayingEvent = function () { - if (this.ee.getListeners('streamPlaying').length > 0) { - this.addPlayEventToFirstVideo(); - } - }; - Publisher.prototype.setPermissionDialogTimer = function (waitTime) { - var _this = this; - this.permissionDialogTimeout = setTimeout(function () { - _this.emitEvent('accessDialogOpened', []); - }, waitTime); - }; - Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { - clearTimeout(this.permissionDialogTimeout); - if ((Date.now() - startTime) > waitTime) { - this.emitEvent('accessDialogClosed', []); - } - }; - return Publisher; -}(StreamManager_1.StreamManager)); -exports.Publisher = Publisher; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Connection_1 = require("./Connection"); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); -var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); -var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); -var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); -var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); -var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var Session = (function () { - function Session(openvidu) { - this.streamManagers = []; - this.remoteStreamsCreated = {}; - this.isFirstIonicIosSubscriber = true; - this.countDownForIonicIosSubscribers = true; - this.remoteConnections = {}; - this.speakingEventsEnabled = false; - this.ee = new EventEmitter(); - this.openvidu = openvidu; - } - Session.prototype.connect = function (token, metadata) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.processToken(token); - if (_this.openvidu.checkSystemRequirements()) { - _this.options = { - sessionId: _this.sessionId, - participantId: token, - metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' - }; - _this.connectAux(token).then(function () { - resolve(); - }).catch(function (error) { - reject(error); - }); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); - } - }); - }; - Session.prototype.disconnect = function () { - this.leave(false, 'disconnect'); - }; - Session.prototype.subscribe = function (stream, targetElement, param3, param4) { - var properties = {}; - if (!!param3 && typeof param3 !== 'function') { - properties = { - insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, - subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true - }; - } - else { - properties = { - insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, - subscribeToAudio: true, - subscribeToVideo: true - }; - } - var completionHandler; - if (!!param3 && (typeof param3 === 'function')) { - completionHandler = param3; - } - else if (!!param4) { - completionHandler = param4; - } - console.info('Subscribing to ' + stream.connection.connectionId); - stream.subscribe() - .then(function () { - console.info('Subscribed correctly to ' + stream.connection.connectionId); - if (completionHandler !== undefined) { - completionHandler(undefined); - } - }) - .catch(function (error) { - if (completionHandler !== undefined) { - completionHandler(error); - } - }); - var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); - if (!!subscriber.targetElement) { - stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); - } - return subscriber; - }; - Session.prototype.subscribeAsync = function (stream, targetElement, properties) { - var _this = this; - return new Promise(function (resolve, reject) { - var subscriber; - var callback = function (error) { - if (!!error) { - reject(error); - } - else { - resolve(subscriber); - } - }; - if (!!properties) { - subscriber = _this.subscribe(stream, targetElement, properties, callback); - } - else { - subscriber = _this.subscribe(stream, targetElement, callback); - } - }); - }; - Session.prototype.unsubscribe = function (subscriber) { - var connectionId = subscriber.stream.connection.connectionId; - console.info('Unsubscribing from ' + connectionId); - this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { - if (error) { - console.error('Error unsubscribing from ' + connectionId, error); - } - else { - console.info('Unsubscribed correctly from ' + connectionId); - } - subscriber.stream.disposeWebRtcPeer(); - subscriber.stream.disposeMediaStream(); - }); - subscriber.stream.streamManager.removeAllVideos(); - }; - Session.prototype.publish = function (publisher) { - var _this = this; - return new Promise(function (resolve, reject) { - publisher.session = _this; - publisher.stream.session = _this; - if (!publisher.stream.publishedOnce) { - _this.connection.addStream(publisher.stream); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - publisher.initialize() - .then(function () { - _this.connection.addStream(publisher.stream); - publisher.reestablishStreamPlayingEvent(); - publisher.stream.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - Session.prototype.unpublish = function (publisher) { - var stream = publisher.stream; - if (!stream.connection) { - console.error('The associated Connection object of this Publisher is null', stream); - return; - } - else if (stream.connection !== this.connection) { - console.error('The associated Connection object of this Publisher is not your local Connection.' + - "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); - return; - } - else { - console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); - this.openvidu.sendRequest('unpublishVideo', function (error, response) { - if (error) { - console.error(error); - } - else { - console.info('Media unpublished correctly'); - } - }); - stream.disposeWebRtcPeer(); - delete stream.connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); - publisher.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - } - }; - Session.prototype.forceDisconnect = function (connection) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing disconnect for connection ' + connection.connectionId); - _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { - if (error) { - console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); - } - else { - reject(error); - } - } - else { - console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); - resolve(); - } - }); - }); - }; - Session.prototype.forceUnpublish = function (stream) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Forcing unpublish for stream ' + stream.streamId); - _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { - if (error) { - console.error('Error forcing unpublish for Stream ' + stream.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); - } - else { - reject(error); - } - } - else { - console.info('Forcing unpublish correctly for Stream ' + stream.streamId); - resolve(); - } - }); - }); - }; - Session.prototype.signal = function (signal) { - var _this = this; - return new Promise(function (resolve, reject) { - var signalMessage = {}; - if (signal.to && signal.to.length > 0) { - var connectionIds_1 = []; - signal.to.forEach(function (connection) { - connectionIds_1.push(connection.connectionId); - }); - signalMessage['to'] = connectionIds_1; - } - else { - signalMessage['to'] = []; - } - signalMessage['data'] = signal.data ? signal.data : ''; - var typeAux = signal.type ? signal.type : 'signal'; - if (!!typeAux) { - if (typeAux.substring(0, 7) !== 'signal:') { - typeAux = 'signal:' + typeAux; - } - } - signalMessage['type'] = typeAux; - _this.openvidu.sendRequest('sendMessage', { - message: JSON.stringify(signalMessage) - }, function (error, response) { - if (!!error) { - reject(error); - } - else { - resolve(); - } - }); - }); - }; - Session.prototype.on = function (type, handler) { - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by 'Session'", event); - } - else { - console.info("Event '" + type + "' triggered by 'Session'"); - } - handler(event); - }); - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = true; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str && str.hasAudio) { - str.enableOnceSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { - this.speakingEventsEnabled = false; - for (var connectionId in this.remoteConnections) { - var str = this.remoteConnections[connectionId].stream; - if (!!str) { - str.disableSpeakingEvents(); - } - } - } - return this; - }; - Session.prototype.onParticipantJoined = function (response) { - var _this = this; - this.getConnection(response.id, '') - .then(function (connection) { - console.warn('Connection ' + response.id + ' already exists in connections list'); - }) - .catch(function (openViduError) { - var connection = new Connection_1.Connection(_this, response); - _this.remoteConnections[response.id] = connection; - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - }; - Session.prototype.onParticipantLeft = function (msg) { - var _this = this; - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - if (!!connection.stream) { - var stream = connection.stream; - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - delete _this.remoteStreamsCreated[stream.streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - } - delete _this.remoteConnections[connection.connectionId]; - _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onParticipantPublished = function (response) { - var _this = this; - var afterConnectionFound = function (connection) { - _this.remoteConnections[connection.connectionId] = connection; - if (!_this.remoteStreamsCreated[connection.stream.streamId]) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); - } - _this.remoteStreamsCreated[connection.stream.streamId] = true; - }; - var connection; - this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (con) { - connection = con; - response.metadata = con.data; - connection.options = response; - connection.initRemoteStreams(response.streams); - afterConnectionFound(connection); - }) - .catch(function (openViduError) { - connection = new Connection_1.Connection(_this, response); - afterConnectionFound(connection); - }); - }; - Session.prototype.onParticipantUnpublished = function (msg) { - var _this = this; - if (msg.connectionId === this.connection.connectionId) { - this.stopPublisherStream(msg.reason); - } - else { - this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); - _this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); - var streamId = connection.stream.streamId; - delete _this.remoteStreamsCreated[streamId]; - if (Object.keys(_this.remoteStreamsCreated).length === 0) { - _this.isFirstIonicIosSubscriber = true; - _this.countDownForIonicIosSubscribers = true; - } - connection.removeStream(streamId); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.onParticipantEvicted = function (msg) { - if (msg.connectionId === this.connection.connectionId) { - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, msg.reason); - } - } - }; - Session.prototype.onNewMessage = function (msg) { - var _this = this; - console.info('New signal: ' + JSON.stringify(msg)); - this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " - + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) - .then(function (connection) { - _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - if (msg.type !== 'signal') { - _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); - } - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onStreamPropertyChanged = function (msg) { - var _this = this; - var callback = function (connection) { - if (!!connection.stream && connection.stream.streamId === msg.streamId) { - var stream = connection.stream; - var oldValue = void 0; - switch (msg.property) { - case 'audioActive': - oldValue = stream.audioActive; - msg.newValue = msg.newValue === 'true'; - stream.audioActive = msg.newValue; - break; - case 'videoActive': - oldValue = stream.videoActive; - msg.newValue = msg.newValue === 'true'; - stream.videoActive = msg.newValue; - break; - case 'videoDimensions': - oldValue = stream.videoDimensions; - msg.newValue = JSON.parse(JSON.parse(msg.newValue)); - stream.videoDimensions = msg.newValue; - break; - case 'filter': - oldValue = stream.filter; - msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; - if (msg.newValue !== undefined) { - stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); - stream.filter.stream = stream; - if (msg.newValue.lastExecMethod) { - stream.filter.lastExecMethod = msg.newValue.lastExecMethod; - } - } - else { - delete stream.filter; - } - msg.newValue = stream.filter; - break; - } - _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - if (!!stream.streamManager) { - stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); - } - } - else { - console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); - } - }; - if (msg.connectionId === this.connection.connectionId) { - callback(this.connection); - } - else { - this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(function (connection) { - callback(connection); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - } - }; - Session.prototype.recvIceCandidate = function (msg) { - var candidate = { - candidate: msg.candidate, - component: msg.component, - foundation: msg.foundation, - ip: msg.ip, - port: msg.port, - priority: msg.priority, - protocol: msg.protocol, - relatedAddress: msg.relatedAddress, - relatedPort: msg.relatedPort, - sdpMid: msg.sdpMid, - sdpMLineIndex: msg.sdpMLineIndex, - tcpType: msg.tcpType, - usernameFragment: msg.usernameFragment, - type: msg.type, - toJSON: function () { - return { candidate: msg.candidate }; - } - }; - this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) - .then(function (connection) { - var stream = connection.stream; - stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { - console.error('Error adding candidate for ' + stream.streamId - + ' stream of endpoint ' + msg.endpointName + ': ' + error); - }); - }) - .catch(function (openViduError) { - console.error(openViduError); - }); - }; - Session.prototype.onSessionClosed = function (msg) { - console.info('Session closed: ' + JSON.stringify(msg)); - var s = msg.sessionId; - if (s !== undefined) { - this.ee.emitEvent('session-closed', [{ - session: s - }]); - } - else { - console.warn('Session undefined on session closed', msg); - } - }; - Session.prototype.onLostConnection = function (reason) { - console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); - if (!!this.sessionId && !this.connection.disposed) { - this.leave(true, reason); - } - }; - Session.prototype.onRecoveredConnection = function () { - console.warn('Recovered connection in Session ' + this.sessionId); - }; - Session.prototype.onMediaError = function (params) { - console.error('Media error: ' + JSON.stringify(params)); - var err = params.error; - if (err) { - this.ee.emitEvent('error-media', [{ - error: err - }]); - } - else { - console.warn('Received undefined media error. Params:', params); - } - }; - Session.prototype.onRecordingStarted = function (response) { - this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); - }; - Session.prototype.onRecordingStopped = function (response) { - this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); - }; - Session.prototype.onFilterEventDispatched = function (response) { - var connectionId = response.connectionId; - var streamId = response.streamId; - this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) - .then(function (connection) { - console.info('Filter event dispatched'); - var stream = connection.stream; - stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); - }); - }; - Session.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - Session.prototype.leave = function (forced, reason) { - var _this = this; - forced = !!forced; - console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection) { - if (!this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', function (error, response) { - if (error) { - console.error(error); - } - _this.openvidu.closeWs(); - }); - } - else { - this.openvidu.closeWs(); - } - this.stopPublisherStream(reason); - if (!this.connection.disposed) { - var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehavior(); - } - } - else { - console.warn('You were not connected to the session ' + this.sessionId); - } - }; - Session.prototype.connectAux = function (token) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.openvidu.startWs(function (error) { - if (!!error) { - reject(error); - } - else { - var joinParams = { - token: (!!token) ? token : '', - session: _this.sessionId, - platform: !!platform.description ? platform.description : 'unknown', - metadata: !!_this.options.metadata ? _this.options.metadata : '', - secret: _this.openvidu.getSecret(), - recorder: _this.openvidu.getRecorder() - }; - _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { - if (!!error) { - reject(error); - } - else { - _this.capabilities = { - subscribe: true, - publish: _this.openvidu.role !== 'SUBSCRIBER', - forceUnpublish: _this.openvidu.role === 'MODERATOR', - forceDisconnect: _this.openvidu.role === 'MODERATOR' - }; - _this.connection = new Connection_1.Connection(_this); - _this.connection.connectionId = response.id; - _this.connection.creationTime = response.createdAt; - _this.connection.data = response.metadata; - _this.connection.rpcSessionId = response.sessionId; - var events_1 = { - connections: new Array(), - streams: new Array() - }; - var existingParticipants = response.value; - existingParticipants.forEach(function (participant) { - var connection = new Connection_1.Connection(_this, participant); - _this.remoteConnections[connection.connectionId] = connection; - events_1.connections.push(connection); - if (!!connection.stream) { - _this.remoteStreamsCreated[connection.stream.streamId] = true; - events_1.streams.push(connection.stream); - } - }); - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); - events_1.connections.forEach(function (connection) { - _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); - }); - events_1.streams.forEach(function (stream) { - _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); - }); - resolve(); - } - }); - } - }); - }); - }; - Session.prototype.stopPublisherStream = function (reason) { - if (!!this.connection.stream) { - this.connection.stream.disposeWebRtcPeer(); - if (this.connection.stream.isLocalStreamPublished) { - this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); - } - } - }; - Session.prototype.stringClientMetadata = function (metadata) { - if (typeof metadata !== 'string') { - return JSON.stringify(metadata); - } - else { - return metadata; - } - }; - Session.prototype.getConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - if (_this.connection.connectionId === connectionId) { - resolve(_this.connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - } - }); - }; - Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { - var _this = this; - return new Promise(function (resolve, reject) { - var connection = _this.remoteConnections[connectionId]; - if (!!connection) { - resolve(connection); - } - else { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); - } - }); - }; - Session.prototype.processToken = function (token) { - var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); - if (!!match) { - var url = { - protocol: match[1], - host: match[2], - hostname: match[3], - port: match[4], - pathname: match[5], - search: match[6], - hash: match[7] - }; - var params = token.split('?'); - var queryParams = decodeURI(params[1]) - .split('&') - .map(function (param) { return param.split('='); }) - .reduce(function (values, _a) { - var key = _a[0], value = _a[1]; - values[key] = value; - return values; - }, {}); - this.sessionId = queryParams['sessionId']; - var secret = queryParams['secret']; - var recorder = queryParams['recorder']; - var turnUsername = queryParams['turnUsername']; - var turnCredential = queryParams['turnCredential']; - var role = queryParams['role']; - var webrtcStatsInterval = queryParams['webrtcStatsInterval']; - var openviduServerVersion = queryParams['version']; - if (!!secret) { - this.openvidu.secret = secret; - } - if (!!recorder) { - this.openvidu.recorder = true; - } - if (!!turnUsername && !!turnCredential) { - var stunUrl = 'stun:' + url.hostname + ':3478'; - var turnUrl1 = 'turn:' + url.hostname + ':3478'; - var turnUrl2 = turnUrl1 + '?transport=tcp'; - this.openvidu.iceServers = [ - { urls: [stunUrl] }, - { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } - ]; - console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); - } - if (!!role) { - this.openvidu.role = role; - } - if (!!webrtcStatsInterval) { - this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; - } - if (!!openviduServerVersion) { - console.info("openvidu-server version: " + openviduServerVersion); - if (openviduServerVersion !== this.openvidu.libraryVersion) { - console.error('OpenVidu Server (' + openviduServerVersion + - ') and OpenVidu Browser (' + this.openvidu.libraryVersion + - ') versions do NOT match. There may be incompatibilities'); - } - } - this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; - this.openvidu.httpUri = 'https://' + url.host; - } - else { - console.error('Token "' + token + '" is not valid'); - } - }; - return Session; -}()); -exports.Session = Session; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Filter_1 = require("./Filter"); -var Subscriber_1 = require("./Subscriber"); -var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); -var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); -var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); -var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); -var EventEmitter = require("wolfy87-eventemitter"); -var hark = require("hark"); -var platform = require("platform"); -var Stream = (function () { - function Stream(session, options) { - var _this = this; - this.ee = new EventEmitter(); - this.isSubscribeToRemote = false; - this.isLocalStreamReadyToPublish = false; - this.isLocalStreamPublished = false; - this.publishedOnce = false; - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - this.volumeChangeEventEnabled = false; - this.session = session; - if (options.hasOwnProperty('id')) { - this.inboundStreamOpts = options; - this.streamId = this.inboundStreamOpts.id; - this.creationTime = this.inboundStreamOpts.createdAt; - this.hasAudio = this.inboundStreamOpts.hasAudio; - this.hasVideo = this.inboundStreamOpts.hasVideo; - if (this.hasAudio) { - this.audioActive = this.inboundStreamOpts.audioActive; - } - if (this.hasVideo) { - this.videoActive = this.inboundStreamOpts.videoActive; - this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; - this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; - this.videoDimensions = this.inboundStreamOpts.videoDimensions; - } - if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { - if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { - delete this.inboundStreamOpts.filter.lastExecMethod; - } - this.filter = this.inboundStreamOpts.filter; - } - } - else { - this.outboundStreamOpts = options; - this.hasAudio = this.isSendAudio(); - this.hasVideo = this.isSendVideo(); - if (this.hasAudio) { - this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; - } - if (this.hasVideo) { - this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; - this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; - if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { - this.typeOfVideo = 'CUSTOM'; - } - else { - this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; - } - } - if (!!this.outboundStreamOpts.publisherProperties.filter) { - this.filter = this.outboundStreamOpts.publisherProperties.filter; - } - } - this.ee.on('mediastream-updated', function () { - _this.streamManager.updateMediaStream(_this.mediaStream); - console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); - }); - } - Stream.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.once = function (type, handler) { - var _this = this; - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); - } - else { - console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); - } - handler(event); - }); - return this; - }; - Stream.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - return this; - }; - Stream.prototype.applyFilter = function (type, options) { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Applying filter to stream ' + _this.streamId); - options = !!options ? options : {}; - if (typeof options !== 'string') { - options = JSON.stringify(options); - } - _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { - if (error) { - console.error('Error applying filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully applied on Stream ' + _this.streamId); - var oldValue = _this.filter; - _this.filter = new Filter_1.Filter(type, options); - _this.filter.stream = _this; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(_this.filter); - } - }); - }); - }; - Stream.prototype.removeFilter = function () { - var _this = this; - return new Promise(function (resolve, reject) { - console.info('Removing filter of stream ' + _this.streamId); - _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { - if (error) { - console.error('Error removing filter for Stream ' + _this.streamId, error); - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); - } - else { - reject(error); - } - } - else { - console.info('Filter successfully removed from Stream ' + _this.streamId); - var oldValue = _this.filter; - delete _this.filter; - _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); - resolve(); - } - }); - }); - }; - Stream.prototype.getMediaStream = function () { - return this.mediaStream; - }; - Stream.prototype.setMediaStream = function (mediaStream) { - this.mediaStream = mediaStream; - }; - Stream.prototype.updateMediaStreamInVideos = function () { - this.ee.emitEvent('mediastream-updated', []); - }; - Stream.prototype.getWebRtcPeer = function () { - return this.webRtcPeer; - }; - Stream.prototype.getRTCPeerConnection = function () { - return this.webRtcPeer.pc; - }; - Stream.prototype.subscribeToMyRemote = function (value) { - this.isSubscribeToRemote = value; - }; - Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { - this.outboundStreamOpts = outboundStreamOpts; - }; - Stream.prototype.subscribe = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.initWebRtcPeerReceive() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - }; - Stream.prototype.publish = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocalStreamReadyToPublish) { - _this.initWebRtcPeerSend() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - } - else { - _this.ee.once('stream-ready-to-publish', function () { - _this.publish() - .then(function () { - resolve(); - }) - .catch(function (error) { - reject(error); - }); - }); - } - }); - }; - Stream.prototype.disposeWebRtcPeer = function () { - if (this.webRtcPeer) { - var isSenderAndCustomTrack = !!this.outboundStreamOpts && - typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; - this.webRtcPeer.dispose(isSenderAndCustomTrack); - } - if (this.speechEvent) { - this.speechEvent.stop(); - delete this.speechEvent; - } - this.stopWebRtcStats(); - console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); - }; - Stream.prototype.disposeMediaStream = function () { - if (this.mediaStream) { - this.mediaStream.getAudioTracks().forEach(function (track) { - track.stop(); - }); - this.mediaStream.getVideoTracks().forEach(function (track) { - track.stop(); - }); - delete this.mediaStream; - } - console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); - }; - Stream.prototype.displayMyRemote = function () { - return this.isSubscribeToRemote; - }; - Stream.prototype.isSendAudio = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.audioSource !== null && - this.outboundStreamOpts.publisherProperties.audioSource !== false); - }; - Stream.prototype.isSendVideo = function () { - return (!!this.outboundStreamOpts && - this.outboundStreamOpts.publisherProperties.videoSource !== null && - this.outboundStreamOpts.publisherProperties.videoSource !== false); - }; - Stream.prototype.isSendScreen = function () { - var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; - if (platform.name === 'Electron') { - screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && - this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); - } - return !!this.outboundStreamOpts && screen; - }; - Stream.prototype.setSpeechEventIfNotExists = function () { - if (!this.speechEvent) { - var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; - harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; - harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; - this.speechEvent = hark(this.mediaStream, harkOptions); - } - }; - Stream.prototype.enableSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.on('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.on('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - }); - } - }; - Stream.prototype.enableOnceSpeakingEvents = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.publisherStartSpeakingEventEnabled) { - this.publisherStartSpeakingEventEnabled = true; - this.speechEvent.once('speaking', function () { - _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - if (!this.publisherStopSpeakingEventEnabled) { - this.publisherStopSpeakingEventEnabled = true; - this.speechEvent.once('stopped_speaking', function () { - _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); - _this.disableSpeakingEvents(); - }); - } - }; - Stream.prototype.disableSpeakingEvents = function () { - if (!!this.speechEvent) { - if (this.volumeChangeEventEnabled) { - this.speechEvent.off('speaking'); - this.speechEvent.off('stopped_speaking'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.publisherStartSpeakingEventEnabled = false; - this.publisherStopSpeakingEventEnabled = false; - }; - Stream.prototype.enableVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.on('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.enableOnceVolumeChangeEvent = function () { - var _this = this; - this.setSpeechEventIfNotExists(); - if (!this.volumeChangeEventEnabled) { - this.volumeChangeEventEnabled = true; - this.speechEvent.once('volume_change', function (harkEvent) { - var oldValue = _this.speechEvent.oldVolumeValue; - var value = { newValue: harkEvent, oldValue: oldValue }; - _this.speechEvent.oldVolumeValue = harkEvent; - _this.disableVolumeChangeEvent(); - _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); - }); - } - }; - Stream.prototype.disableVolumeChangeEvent = function () { - if (!!this.speechEvent) { - if (this.session.speakingEventsEnabled) { - this.speechEvent.off('volume_change'); - } - else { - this.speechEvent.stop(); - delete this.speechEvent; - } - } - this.volumeChangeEventEnabled = false; - }; - Stream.prototype.isLocal = function () { - return (!this.inboundStreamOpts && !!this.outboundStreamOpts); - }; - Stream.prototype.getSelectedIceCandidate = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.webRtcStats.getSelectedIceCandidateInfo() - .then(function (report) { return resolve(report); }) - .catch(function (error) { return reject(error); }); - }); - }; - Stream.prototype.getRemoteIceCandidateList = function () { - return this.webRtcPeer.remoteCandidatesQueue; - }; - Stream.prototype.getLocalIceCandidateList = function () { - return this.webRtcPeer.localCandidatesQueue; - }; - Stream.prototype.initWebRtcPeerSend = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var userMediaConstraints = { - audio: _this.isSendAudio(), - video: _this.isSendVideo() - }; - var options = { - mediaStream: _this.mediaStream, - mediaConstraints: userMediaConstraints, - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to publish as ' - + _this.streamId, sdpOfferParam); - var typeOfVideo = ''; - if (_this.isSendVideo()) { - typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); - } - _this.session.openvidu.sendRequest('publishVideo', { - sdpOffer: sdpOfferParam, - doLoopback: _this.displayMyRemote() || false, - hasAudio: _this.isSendAudio(), - hasVideo: _this.isSendVideo(), - audioActive: _this.audioActive, - videoActive: _this.videoActive, - typeOfVideo: typeOfVideo, - frameRate: !!_this.frameRate ? _this.frameRate : -1, - videoDimensions: JSON.stringify(_this.videoDimensions), - filter: _this.outboundStreamOpts.publisherProperties.filter - }, function (error, response) { - if (error) { - if (error.code === 401) { - reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); - } - else { - reject('Error on publishVideo: ' + JSON.stringify(error)); - } - } - else { - _this.webRtcPeer.processAnswer(response.sdpAnswer, false) - .then(function () { - _this.streamId = response.id; - _this.creationTime = response.createdAt; - _this.isLocalStreamPublished = true; - _this.publishedOnce = true; - if (_this.displayMyRemote()) { - _this.remotePeerSuccessfullyEstablished(); - } - _this.ee.emitEvent('stream-created-by-publisher', []); - _this.initWebRtcStats(); - resolve(); - }) - .catch(function (error) { - reject(error); - }); - console.info("'Publisher' successfully published to session"); - } - }); - }; - if (_this.displayMyRemote()) { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); - } - else { - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); - } - _this.webRtcPeer.generateOffer().then(function (offer) { - successCallback(offer); - }).catch(function (error) { - reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.initWebRtcPeerReceive = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerConstraints = { - audio: _this.inboundStreamOpts.hasAudio, - video: _this.inboundStreamOpts.hasVideo - }; - console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); - var options = { - onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), - mediaConstraints: offerConstraints, - iceServers: _this.getIceServersConf(), - simulcast: false - }; - var successCallback = function (sdpOfferParam) { - console.debug('Sending SDP offer to subscribe to ' - + _this.streamId, sdpOfferParam); - _this.session.openvidu.sendRequest('receiveVideoFrom', { - sender: _this.streamId, - sdpOffer: sdpOfferParam - }, function (error, response) { - if (error) { - reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); - } - else { - if (_this.session.isFirstIonicIosSubscriber) { - _this.session.isFirstIonicIosSubscriber = false; - _this.session['iosInterval'] = setTimeout(function () { - _this.session.countDownForIonicIosSubscribers = false; - }, 400); - } - var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers; - _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () { - _this.remotePeerSuccessfullyEstablished(); - _this.initWebRtcStats(); - resolve(); - }).catch(function (error) { - reject(error); - }); - } - }); - }; - _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); - _this.webRtcPeer.generateOffer() - .then(function (offer) { - successCallback(offer); - }) - .catch(function (error) { - reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); - }); - }); - }; - Stream.prototype.remotePeerSuccessfullyEstablished = function () { - if (platform['isIonicIos']) { - var pc1 = this.webRtcPeer.pc; - this.mediaStream = pc1.getRemoteStreams()[0]; - } - else { - this.mediaStream = new MediaStream(); - var receiver = void 0; - for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { - receiver = _a[_i]; - if (!!receiver.track) { - this.mediaStream.addTrack(receiver.track); - } - } - } - console.debug('Peer remote stream', this.mediaStream); - if (!!this.mediaStream) { - if (this.streamManager instanceof Subscriber_1.Subscriber) { - if (!!this.mediaStream.getAudioTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToAudio); - this.mediaStream.getAudioTracks()[0].enabled = enabled; - } - if (!!this.mediaStream.getVideoTracks()[0]) { - var enabled = !!(this.streamManager.properties.subscribeToVideo); - this.mediaStream.getVideoTracks()[0].enabled = enabled; - } - } - this.updateMediaStreamInVideos(); - if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { - this.enableSpeakingEvents(); - } - } - }; - Stream.prototype.initWebRtcStats = function () { - this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); - this.webRtcStats.initWebRtcStats(); - }; - Stream.prototype.stopWebRtcStats = function () { - if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { - this.webRtcStats.stopWebRtcStats(); - } - }; - Stream.prototype.getIceServersConf = function () { - var returnValue; - if (!!this.session.openvidu.advancedConfiguration.iceServers) { - returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? - undefined : - this.session.openvidu.advancedConfiguration.iceServers; - } - else if (this.session.openvidu.iceServers) { - returnValue = this.session.openvidu.iceServers; - } - else { - returnValue = undefined; - } - return returnValue; - }; - Stream.prototype.gatherStatsForPeer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.isLocal()) { - _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'outbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesEncoded'] = report.framesEncoded; - } - finalReport['packetsSent'] = report.packetsSent; - finalReport['bytesSent'] = report.bytesSent; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - else { - _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() - .then(function (response) { - response.forEach(function (report) { - if (_this.isReportWanted(report)) { - var finalReport = {}; - finalReport['type'] = report.type; - finalReport['timestamp'] = report.timestamp; - finalReport['id'] = report.id; - if (report.type === 'inbound-rtp') { - finalReport['ssrc'] = report.ssrc; - finalReport['firCount'] = report.firCount; - finalReport['pliCount'] = report.pliCount; - finalReport['nackCount'] = report.nackCount; - finalReport['qpSum'] = report.qpSum; - if (!!report.kind) { - finalReport['mediaType'] = report.kind; - } - else if (!!report.mediaType) { - finalReport['mediaType'] = report.mediaType; - } - else { - finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; - } - if (finalReport['mediaType'] === 'video') { - finalReport['framesDecoded'] = report.framesDecoded; - } - finalReport['packetsReceived'] = report.packetsReceived; - finalReport['packetsLost'] = report.packetsLost; - finalReport['jitter'] = report.jitter; - finalReport['bytesReceived'] = report.bytesReceived; - } - if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { - finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; - finalReport['rtt'] = report.currentRoundTripTime; - finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; - } - if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { - } - console.log(finalReport); - } - }); - }); }); - } - }); - }; - Stream.prototype.isReportWanted = function (report) { - return report.type === 'inbound-rtp' && !this.isLocal() || - report.type === 'outbound-rtp' && this.isLocal() || - (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); - }; - return Stream; -}()); -exports.Stream = Stream; - -},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); -var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); -var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); -var EventEmitter = require("wolfy87-eventemitter"); -var platform = require("platform"); -var StreamManager = (function () { - function StreamManager(stream, targetElement) { - var _this = this; - this.videos = []; - this.lazyLaunchVideoElementCreatedEvent = false; - this.ee = new EventEmitter(); - this.stream = stream; - this.stream.streamManager = this; - this.remote = !this.stream.isLocal(); - if (!!targetElement) { - var targEl = void 0; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - if (!!targEl) { - this.firstVideoElement = { - targetElement: targEl, - video: document.createElement('video'), - id: '', - canplayListenerAdded: false - }; - if (platform.name === 'Safari') { - this.firstVideoElement.video.setAttribute('playsinline', 'true'); - } - this.targetElement = targEl; - this.element = targEl; - } - } - this.canPlayListener = function () { - if (_this.stream.isLocal()) { - if (!_this.stream.displayMyRemote()) { - console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - else { - console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); - } - } - else { - console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); - _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); - } - _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); - }; - } - StreamManager.prototype.on = function (type, handler) { - var _this = this; - this.ee.on(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); - } - else { - console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = false; - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.once = function (type, handler) { - this.ee.once(type, function (event) { - if (event) { - console.info("Event '" + type + "' triggered once", event); - } - else { - console.info("Event '" + type + "' triggered once"); - } - handler(event); - }); - if (type === 'videoElementCreated') { - if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); - } - } - if (type === 'streamPlaying' || type === 'videoPlaying') { - if (this.videos[0] && this.videos[0].video && - this.videos[0].video.currentTime > 0 && - this.videos[0].video.paused === false && - this.videos[0].video.ended === false && - this.videos[0].video.readyState === 4) { - this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); - this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); - } - } - if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { - this.stream.enableOnceVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.off = function (type, handler) { - if (!handler) { - this.ee.removeAllListeners(type); - } - else { - this.ee.off(type, handler); - } - if (type === 'streamAudioVolumeChange') { - this.stream.disableVolumeChangeEvent(); - } - return this; - }; - StreamManager.prototype.addVideoElement = function (video) { - this.initializeVideoProperties(video); - if (this.stream.isLocal() && this.stream.displayMyRemote()) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { - var v = _a[_i]; - if (v.video === video) { - return 0; - } - } - var returnNumber = 1; - for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { - var streamManager = _c[_b]; - if (streamManager.disassociateVideo(video)) { - returnNumber = -1; - break; - } - } - this.stream.session.streamManagers.forEach(function (streamManager) { - streamManager.disassociateVideo(video); - }); - this.pushNewStreamManagerVideo({ - video: video, - id: video.id, - canplayListenerAdded: false - }); - console.info('New video element associated to ', this); - return returnNumber; - }; - StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { - var targEl; - if (typeof targetElement === 'string') { - targEl = document.getElementById(targetElement); - if (!targEl) { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - } - else if (targetElement instanceof HTMLElement) { - targEl = targetElement; - } - else { - throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); - } - var video = document.createElement('video'); - this.initializeVideoProperties(video); - var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; - switch (insMode) { - case VideoInsertMode_1.VideoInsertMode.AFTER: - targEl.parentNode.insertBefore(video, targEl.nextSibling); - break; - case VideoInsertMode_1.VideoInsertMode.APPEND: - targEl.appendChild(video); - break; - case VideoInsertMode_1.VideoInsertMode.BEFORE: - targEl.parentNode.insertBefore(video, targEl); - break; - case VideoInsertMode_1.VideoInsertMode.PREPEND: - targEl.insertBefore(video, targEl.childNodes[0]); - break; - case VideoInsertMode_1.VideoInsertMode.REPLACE: - targEl.parentNode.replaceChild(video, targEl); - break; - default: - insMode = VideoInsertMode_1.VideoInsertMode.APPEND; - targEl.appendChild(video); - break; - } - var v = { - targetElement: targEl, - video: video, - insertMode: insMode, - id: video.id, - canplayListenerAdded: false - }; - this.pushNewStreamManagerVideo(v); - this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); - this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; - return video; - }; - StreamManager.prototype.initializeVideoProperties = function (video) { - if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { - if (video.srcObject !== this.stream.getMediaStream()) { - video.srcObject = this.stream.getMediaStream(); - } - } - video.autoplay = true; - video.controls = false; - if (platform.name === 'Safari') { - video.setAttribute('playsinline', 'true'); - } - if (!video.id) { - video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; - if (!this.id && !!this.targetElement) { - this.id = video.id; - } - } - if (!this.remote && !this.stream.displayMyRemote()) { - video.muted = true; - if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { - this.removeMirrorVideo(video); - } - else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { - this.mirrorVideo(video); - } - } - }; - StreamManager.prototype.removeAllVideos = function () { - var _this = this; - for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { - if (this.stream.session.streamManagers[i] === this) { - this.stream.session.streamManagers.splice(i, 1); - } - } - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); - streamManagerVideo.canplayListenerAdded = false; - if (!!streamManagerVideo.targetElement) { - streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); - _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); - } - streamManagerVideo.video.srcObject = null; - _this.videos.filter(function (v) { return !v.targetElement; }); - }); - }; - StreamManager.prototype.disassociateVideo = function (video) { - var disassociated = false; - for (var i = 0; i < this.videos.length; i++) { - if (this.videos[i].video === video) { - this.videos[i].video.removeEventListener('canplay', this.canPlayListener); - this.videos.splice(i, 1); - disassociated = true; - console.info('Video element disassociated from ', this); - break; - } - } - return disassociated; - }; - StreamManager.prototype.addPlayEventToFirstVideo = function () { - if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { - this.videos[0].video.addEventListener('canplay', this.canPlayListener); - this.videos[0].canplayListenerAdded = true; - } - }; - StreamManager.prototype.updateMediaStream = function (mediaStream) { - this.videos.forEach(function (streamManagerVideo) { - streamManagerVideo.video.srcObject = mediaStream; - if (platform['isIonicIos']) { - var vParent = streamManagerVideo.video.parentElement; - var newVideo = streamManagerVideo.video; - vParent.replaceChild(newVideo, streamManagerVideo.video); - streamManagerVideo.video = newVideo; - } - }); - }; - StreamManager.prototype.emitEvent = function (type, eventArray) { - this.ee.emitEvent(type, eventArray); - }; - StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { - this.videos.push(streamManagerVideo); - this.addPlayEventToFirstVideo(); - if (this.stream.session.streamManagers.indexOf(this) === -1) { - this.stream.session.streamManagers.push(this); - } - }; - StreamManager.prototype.mirrorVideo = function (video) { - if (!platform['isIonicIos']) { - video.style.transform = 'rotateY(180deg)'; - video.style.webkitTransform = 'rotateY(180deg)'; - } - }; - StreamManager.prototype.removeMirrorVideo = function (video) { - video.style.transform = 'unset'; - video.style.webkitTransform = 'unset'; - }; - return StreamManager; -}()); -exports.StreamManager = StreamManager; - -},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var StreamManager_1 = require("./StreamManager"); -var Subscriber = (function (_super) { - __extends(Subscriber, _super); - function Subscriber(stream, targEl, properties) { - var _this = _super.call(this, stream, targEl) || this; - _this.element = _this.targetElement; - _this.stream = stream; - _this.properties = properties; - return _this; - } - Subscriber.prototype.subscribeToAudio = function (value) { - this.stream.getMediaStream().getAudioTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); - return this; - }; - Subscriber.prototype.subscribeToVideo = function (value) { - this.stream.getMediaStream().getVideoTracks().forEach(function (track) { - track.enabled = value; - }); - console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); - return this; - }; - return Subscriber; -}(StreamManager_1.StreamManager)); -exports.Subscriber = Subscriber; - -},{"./StreamManager":25}],27:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var LocalRecorderState; -(function (LocalRecorderState) { - LocalRecorderState["READY"] = "READY"; - LocalRecorderState["RECORDING"] = "RECORDING"; - LocalRecorderState["PAUSED"] = "PAUSED"; - LocalRecorderState["FINISHED"] = "FINISHED"; -})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); - -},{}],28:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var OpenViduErrorName; -(function (OpenViduErrorName) { - OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; - OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; - OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; - OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; - OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; - OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; - OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; - OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; - OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; - OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; - OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; - OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; - OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; - OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; -})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); -var OpenViduError = (function () { - function OpenViduError(name, message) { - this.name = name; - this.message = message; - } - return OpenViduError; -}()); -exports.OpenViduError = OpenViduError; - -},{}],29:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var VideoInsertMode; -(function (VideoInsertMode) { - VideoInsertMode["AFTER"] = "AFTER"; - VideoInsertMode["APPEND"] = "APPEND"; - VideoInsertMode["BEFORE"] = "BEFORE"; - VideoInsertMode["PREPEND"] = "PREPEND"; - VideoInsertMode["REPLACE"] = "REPLACE"; -})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); - -},{}],30:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var ConnectionEvent = (function (_super) { - __extends(ConnectionEvent, _super); - function ConnectionEvent(cancelable, target, type, connection, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.connection = connection; - _this.reason = reason; - return _this; - } - ConnectionEvent.prototype.callDefaultBehavior = function () { }; - return ConnectionEvent; -}(Event_1.Event)); -exports.ConnectionEvent = ConnectionEvent; - -},{"./Event":31}],31:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Event = (function () { - function Event(cancelable, target, type) { - this.hasBeenPrevented = false; - this.cancelable = cancelable; - this.target = target; - this.type = type; - } - Event.prototype.isDefaultPrevented = function () { - return this.hasBeenPrevented; - }; - Event.prototype.preventDefault = function () { - this.callDefaultBehavior = function () { }; - this.hasBeenPrevented = true; - }; - return Event; -}()); -exports.Event = Event; - -},{}],32:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var FilterEvent = (function (_super) { - __extends(FilterEvent, _super); - function FilterEvent(target, eventType, data) { - var _this = _super.call(this, false, target, eventType) || this; - _this.data = data; - return _this; - } - FilterEvent.prototype.callDefaultBehavior = function () { }; - return FilterEvent; -}(Event_1.Event)); -exports.FilterEvent = FilterEvent; - -},{"./Event":31}],33:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var PublisherSpeakingEvent = (function (_super) { - __extends(PublisherSpeakingEvent, _super); - function PublisherSpeakingEvent(target, type, connection, streamId) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.connection = connection; - _this.streamId = streamId; - return _this; - } - PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; - return PublisherSpeakingEvent; -}(Event_1.Event)); -exports.PublisherSpeakingEvent = PublisherSpeakingEvent; - -},{"./Event":31}],34:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var RecordingEvent = (function (_super) { - __extends(RecordingEvent, _super); - function RecordingEvent(target, type, id, name, reason) { - var _this = _super.call(this, false, target, type) || this; - _this.id = id; - if (name !== id) { - _this.name = name; - } - _this.reason = reason; - return _this; - } - RecordingEvent.prototype.callDefaultBehavior = function () { }; - return RecordingEvent; -}(Event_1.Event)); -exports.RecordingEvent = RecordingEvent; - -},{"./Event":31}],35:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SessionDisconnectedEvent = (function (_super) { - __extends(SessionDisconnectedEvent, _super); - function SessionDisconnectedEvent(target, reason) { - var _this = _super.call(this, true, target, 'sessionDisconnected') || this; - _this.reason = reason; - return _this; - } - SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - var session = this.target; - for (var connectionId in session.remoteConnections) { - if (!!session.remoteConnections[connectionId].stream) { - session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); - session.remoteConnections[connectionId].stream.disposeMediaStream(); - if (session.remoteConnections[connectionId].stream.streamManager) { - session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); - } - delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; - session.remoteConnections[connectionId].dispose(); - } - delete session.remoteConnections[connectionId]; - } - }; - return SessionDisconnectedEvent; -}(Event_1.Event)); -exports.SessionDisconnectedEvent = SessionDisconnectedEvent; - -},{"./Event":31}],36:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var SignalEvent = (function (_super) { - __extends(SignalEvent, _super); - function SignalEvent(target, type, data, from) { - var _this = _super.call(this, false, target, type) || this; - _this.type = type; - _this.data = data; - _this.from = from; - return _this; - } - SignalEvent.prototype.callDefaultBehavior = function () { }; - return SignalEvent; -}(Event_1.Event)); -exports.SignalEvent = SignalEvent; - -},{"./Event":31}],37:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var Publisher_1 = require("../../OpenVidu/Publisher"); -var Session_1 = require("../../OpenVidu/Session"); -var StreamEvent = (function (_super) { - __extends(StreamEvent, _super); - function StreamEvent(cancelable, target, type, stream, reason) { - var _this = _super.call(this, cancelable, target, type) || this; - _this.stream = stream; - _this.reason = reason; - return _this; - } - StreamEvent.prototype.callDefaultBehavior = function () { - if (this.type === 'streamDestroyed') { - if (this.target instanceof Session_1.Session) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); - this.stream.disposeWebRtcPeer(); - } - else if (this.target instanceof Publisher_1.Publisher) { - console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); - clearInterval(this.target.screenShareResizeInterval); - this.stream.isLocalStreamReadyToPublish = false; - var openviduPublishers = this.target.openvidu.publishers; - for (var i = 0; i < openviduPublishers.length; i++) { - if (openviduPublishers[i] === this.target) { - openviduPublishers.splice(i, 1); - break; - } - } - } - this.stream.disposeMediaStream(); - if (this.stream.streamManager) - this.stream.streamManager.removeAllVideos(); - delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; - var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; - if (!!remoteConnection && !!remoteConnection.options) { - var streamOptionsServer = remoteConnection.options.streams; - for (var i = streamOptionsServer.length - 1; i >= 0; --i) { - if (streamOptionsServer[i].id === this.stream.streamId) { - streamOptionsServer.splice(i, 1); - } - } - } - } - }; - return StreamEvent; -}(Event_1.Event)); -exports.StreamEvent = StreamEvent; - -},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamManagerEvent = (function (_super) { - __extends(StreamManagerEvent, _super); - function StreamManagerEvent(target, type, value) { - var _this = _super.call(this, false, target, type) || this; - _this.value = value; - return _this; - } - StreamManagerEvent.prototype.callDefaultBehavior = function () { }; - return StreamManagerEvent; -}(Event_1.Event)); -exports.StreamManagerEvent = StreamManagerEvent; - -},{"./Event":31}],39:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var StreamPropertyChangedEvent = (function (_super) { - __extends(StreamPropertyChangedEvent, _super); - function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { - var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; - _this.stream = stream; - _this.changedProperty = changedProperty; - _this.newValue = newValue; - _this.oldValue = oldValue; - _this.reason = reason; - return _this; - } - StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; - return StreamPropertyChangedEvent; -}(Event_1.Event)); -exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; - -},{"./Event":31}],40:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var Event_1 = require("./Event"); -var VideoElementEvent = (function (_super) { - __extends(VideoElementEvent, _super); - function VideoElementEvent(element, target, type) { - var _this = _super.call(this, false, target, type) || this; - _this.element = element; - return _this; - } - VideoElementEvent.prototype.callDefaultBehavior = function () { }; - return VideoElementEvent; -}(Event_1.Event)); -exports.VideoElementEvent = VideoElementEvent; - -},{"./Event":31}],41:[function(require,module,exports){ -function Mapper() { - var sources = {}; - this.forEach = function (callback) { - for (var key in sources) { - var source = sources[key]; - for (var key2 in source) - callback(source[key2]); - } - ; - }; - this.get = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return undefined; - return ids[id]; - }; - this.remove = function (id, source) { - var ids = sources[source]; - if (ids == undefined) - return; - delete ids[id]; - for (var i in ids) { - return false; - } - delete sources[source]; - }; - this.set = function (value, id, source) { - if (value == undefined) - return this.remove(id, source); - var ids = sources[source]; - if (ids == undefined) - sources[source] = ids = {}; - ids[id] = value; - }; -} -; -Mapper.prototype.pop = function (id, source) { - var value = this.get(id, source); - if (value == undefined) - return undefined; - this.remove(id, source); - return value; -}; -module.exports = Mapper; - -},{}],42:[function(require,module,exports){ -var JsonRpcClient = require('./jsonrpcclient'); -exports.JsonRpcClient = JsonRpcClient; - -},{"./jsonrpcclient":43}],43:[function(require,module,exports){ -var RpcBuilder = require('../'); -var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); -Date.now = Date.now || function () { - return +new Date; -}; -var PING_INTERVAL = 5000; -var RECONNECTING = 'RECONNECTING'; -var CONNECTED = 'CONNECTED'; -var DISCONNECTED = 'DISCONNECTED'; -var Logger = console; -function JsonRpcClient(configuration) { - var self = this; - var wsConfig = configuration.ws; - var notReconnectIfNumLessThan = -1; - var pingNextNum = 0; - var enabledPings = true; - var pingPongStarted = false; - var pingInterval; - var status = DISCONNECTED; - var onreconnecting = wsConfig.onreconnecting; - var onreconnected = wsConfig.onreconnected; - var onconnected = wsConfig.onconnected; - var onerror = wsConfig.onerror; - configuration.rpc.pull = function (params, request) { - request.reply(null, "push"); - }; - wsConfig.onreconnecting = function () { - Logger.debug("--------- ONRECONNECTING -----------"); - if (status === RECONNECTING) { - Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); - return; - } - stopPing(); - status = RECONNECTING; - if (onreconnecting) { - onreconnecting(); - } - }; - wsConfig.onreconnected = function () { - Logger.debug("--------- ONRECONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - updateNotReconnectIfLessThan(); - if (onreconnected) { - onreconnected(); - } - }; - wsConfig.onconnected = function () { - Logger.debug("--------- ONCONNECTED -----------"); - if (status === CONNECTED) { - Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); - return; - } - status = CONNECTED; - enabledPings = true; - usePing(); - if (onconnected) { - onconnected(); - } - }; - wsConfig.onerror = function (error) { - Logger.debug("--------- ONERROR -----------"); - status = DISCONNECTED; - stopPing(); - if (onerror) { - onerror(error); - } - }; - var ws = new WebSocketWithReconnection(wsConfig); - Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); - var rpcBuilderOptions = { - request_timeout: configuration.rpc.requestTimeout, - ping_request_timeout: configuration.rpc.heartbeatRequestTimeout - }; - var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { - Logger.debug('Received request: ' + JSON.stringify(request)); - try { - var func = configuration.rpc[request.method]; - if (func === undefined) { - Logger.error("Method " + request.method + " not registered in client"); - } - else { - func(request.params, request); - } - } - catch (err) { - Logger.error('Exception processing request: ' + JSON.stringify(request)); - Logger.error(err); - } - }); - this.send = function (method, params, callback) { - if (method !== 'ping') { - Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); - } - var requestTime = Date.now(); - rpc.encode(method, params, function (error, result) { - if (error) { - try { - Logger.error("ERROR:" + error.message + " in Request: method:" + - method + " params:" + JSON.stringify(params) + " request:" + - error.request); - if (error.data) { - Logger.error("ERROR DATA:" + JSON.stringify(error.data)); - } - } - catch (e) { } - error.requestTime = requestTime; - } - if (callback) { - if (result != undefined && result.value !== 'pong') { - Logger.debug('Response: ' + JSON.stringify(result)); - } - callback(error, result); - } - }); - }; - function updateNotReconnectIfLessThan() { - Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + - notReconnectIfNumLessThan + ')'); - notReconnectIfNumLessThan = pingNextNum; - } - function sendPing() { - if (enabledPings) { - var params = null; - if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { - params = { - interval: configuration.heartbeat || PING_INTERVAL - }; - } - pingNextNum++; - self.send('ping', params, (function (pingNum) { - return function (error, result) { - if (error) { - Logger.debug("Error in ping request #" + pingNum + " (" + - error.message + ")"); - if (pingNum > notReconnectIfNumLessThan) { - enabledPings = false; - updateNotReconnectIfLessThan(); - Logger.debug("Server did not respond to ping message #" + - pingNum + ". Reconnecting... "); - ws.reconnectWs(); - } - } - }; - })(pingNextNum)); - } - else { - Logger.debug("Trying to send ping, but ping is not enabled"); - } - } - function usePing() { - if (!pingPongStarted) { - Logger.debug("Starting ping (if configured)"); - pingPongStarted = true; - if (configuration.heartbeat != undefined) { - pingInterval = setInterval(sendPing, configuration.heartbeat); - sendPing(); - } - } - } - function stopPing() { - clearInterval(pingInterval); - pingPongStarted = false; - enabledPings = false; - pingNextNum = -1; - rpc.cancel(); - } - this.close = function (code, reason) { - Logger.debug("Closing with code: " + code + " because: " + reason); - if (pingInterval != undefined) { - Logger.debug("Clearing ping interval"); - clearInterval(pingInterval); - } - pingPongStarted = false; - enabledPings = false; - if (configuration.sendCloseMessage) { - Logger.debug("Sending close message"); - this.send('closeSession', null, function (error, result) { - if (error) { - Logger.error("Error sending close message: " + JSON.stringify(error)); - } - ws.close(code, reason); - }); - } - else { - ws.close(code, reason); - } - }; - this.forceClose = function (millis) { - ws.forceClose(millis); - }; - this.reconnect = function () { - ws.reconnectWs(); - }; - this.resetPing = function () { - enabledPings = true; - pingNextNum = 0; - usePing(); - }; -} -module.exports = JsonRpcClient; - -},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ -var WebSocketWithReconnection = require('./webSocketWithReconnection'); -exports.WebSocketWithReconnection = WebSocketWithReconnection; - -},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ -(function (global){ -"use strict"; -var BrowserWebSocket = global.WebSocket || global.MozWebSocket; -var Logger = console; -var MAX_RETRIES = 2000; -var RETRY_TIME_MS = 3000; -var CONNECTING = 0; -var OPEN = 1; -var CLOSING = 2; -var CLOSED = 3; -function WebSocketWithReconnection(config) { - var closing = false; - var registerMessageHandler; - var wsUri = config.uri; - var useSockJS = config.useSockJS; - var reconnecting = false; - var forcingDisconnection = false; - var ws; - if (useSockJS) { - ws = new SockJS(wsUri); - } - else { - ws = new WebSocket(wsUri); - } - ws.onopen = function () { - logConnected(ws, wsUri); - if (config.onconnected) { - config.onconnected(); - } - }; - ws.onerror = function (error) { - Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); - if (config.onerror) { - config.onerror(error); - } - }; - function logConnected(ws, wsUri) { - try { - Logger.debug("WebSocket connected to " + wsUri); - } - catch (e) { - Logger.error(e); - } - } - var reconnectionOnClose = function () { - if (ws.readyState === CLOSED) { - if (closing) { - Logger.debug("Connection closed by user"); - } - else { - Logger.debug("Connection closed unexpectecly. Reconnecting..."); - reconnectToSameUri(MAX_RETRIES, 1); - } - } - else { - Logger.debug("Close callback from previous websocket. Ignoring it"); - } - }; - ws.onclose = reconnectionOnClose; - function reconnectToSameUri(maxRetries, numRetries) { - Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); - if (numRetries === 1) { - if (reconnecting) { - Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); - return; - } - else { - reconnecting = true; - } - if (config.onreconnecting) { - config.onreconnecting(); - } - } - if (forcingDisconnection) { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - else { - if (config.newWsUriOnReconnection) { - config.newWsUriOnReconnection(function (error, newWsUri) { - if (error) { - Logger.debug(error); - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - else { - reconnectToNewUri(maxRetries, numRetries, newWsUri); - } - }); - } - else { - reconnectToNewUri(maxRetries, numRetries, wsUri); - } - } - } - function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { - Logger.debug("Reconnection attempt #" + numRetries); - ws.close(); - wsUri = reconnectWsUri || wsUri; - var newWs; - if (useSockJS) { - newWs = new SockJS(wsUri); - } - else { - newWs = new WebSocket(wsUri); - } - newWs.onopen = function () { - Logger.debug("Reconnected after " + numRetries + " attempts..."); - logConnected(newWs, wsUri); - reconnecting = false; - registerMessageHandler(); - if (config.onreconnected()) { - config.onreconnected(); - } - newWs.onclose = reconnectionOnClose; - }; - var onErrorOrClose = function (error) { - Logger.warn("Reconnection error: ", error); - if (numRetries === maxRetries) { - if (config.ondisconnect) { - config.ondisconnect(); - } - } - else { - setTimeout(function () { - reconnectToSameUri(maxRetries, numRetries + 1); - }, RETRY_TIME_MS); - } - }; - newWs.onerror = onErrorOrClose; - ws = newWs; - } - this.close = function () { - closing = true; - ws.close(); - }; - this.forceClose = function (millis) { - Logger.debug("Testing: Force WebSocket close"); - if (millis) { - Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); - var goodWsUri = wsUri; - wsUri = "wss://21.234.12.34.4:443/"; - forcingDisconnection = true; - setTimeout(function () { - Logger.debug("Testing: Recover good wsUri " + goodWsUri); - wsUri = goodWsUri; - forcingDisconnection = false; - }, millis); - } - ws.close(); - }; - this.reconnectWs = function () { - Logger.debug("reconnectWs"); - reconnectToSameUri(MAX_RETRIES, 1); - }; - this.send = function (message) { - ws.send(message); - }; - this.addEventListener = function (type, callback) { - registerMessageHandler = function () { - ws.addEventListener(type, callback); - }; - registerMessageHandler(); - }; -} -module.exports = WebSocketWithReconnection; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],46:[function(require,module,exports){ -var defineProperty_IE8 = false; -if (Object.defineProperty) { - try { - Object.defineProperty({}, "x", {}); - } - catch (e) { - defineProperty_IE8 = true; - } -} -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; -} -var EventEmitter = require('events').EventEmitter; -var inherits = require('inherits'); -var packers = require('./packers'); -var Mapper = require('./Mapper'); -var BASE_TIMEOUT = 5000; -function unifyResponseMethods(responseMethods) { - if (!responseMethods) - return {}; - for (var key in responseMethods) { - var value = responseMethods[key]; - if (typeof value == 'string') - responseMethods[key] = - { - response: value - }; - } - ; - return responseMethods; -} -; -function unifyTransport(transport) { - if (!transport) - return; - if (transport instanceof Function) - return { send: transport }; - if (transport.send instanceof Function) - return transport; - if (transport.postMessage instanceof Function) { - transport.send = transport.postMessage; - return transport; - } - if (transport.write instanceof Function) { - transport.send = transport.write; - return transport; - } - if (transport.onmessage !== undefined) - return; - if (transport.pause instanceof Function) - return; - throw new SyntaxError("Transport is not a function nor a valid object"); -} -; -function RpcNotification(method, params) { - if (defineProperty_IE8) { - this.method = method; - this.params = params; - } - else { - Object.defineProperty(this, 'method', { value: method, enumerable: true }); - Object.defineProperty(this, 'params', { value: params, enumerable: true }); - } -} -; -function RpcBuilder(packer, options, transport, onRequest) { - var self = this; - if (!packer) - throw new SyntaxError('Packer is not defined'); - if (!packer.pack || !packer.unpack) - throw new SyntaxError('Packer is invalid'); - var responseMethods = unifyResponseMethods(packer.responseMethods); - if (options instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = options; - transport = undefined; - options = undefined; - } - ; - if (options && options.send instanceof Function) { - if (transport && !(transport instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - onRequest = transport; - transport = options; - options = undefined; - } - ; - if (transport instanceof Function) { - if (onRequest != undefined) - throw new SyntaxError("There can't be parameters after onRequest"); - onRequest = transport; - transport = undefined; - } - ; - if (transport && transport.send instanceof Function) - if (onRequest && !(onRequest instanceof Function)) - throw new SyntaxError("Only a function can be after transport"); - options = options || {}; - EventEmitter.call(this); - if (onRequest) - this.on('request', onRequest); - if (defineProperty_IE8) - this.peerID = options.peerID; - else - Object.defineProperty(this, 'peerID', { value: options.peerID }); - var max_retries = options.max_retries || 0; - function transportMessage(event) { - self.decode(event.data || event); - } - ; - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - if (transport) { - if (transport.removeEventListener) - transport.removeEventListener('message', transportMessage); - else if (transport.removeListener) - transport.removeListener('data', transportMessage); - } - ; - if (value) { - if (value.addEventListener) - value.addEventListener('message', transportMessage); - else if (value.addListener) - value.addListener('data', transportMessage); - } - ; - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - this.setTransport(transport); - var request_timeout = options.request_timeout || BASE_TIMEOUT; - var ping_request_timeout = options.ping_request_timeout || request_timeout; - var response_timeout = options.response_timeout || BASE_TIMEOUT; - var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; - var requestID = 0; - var requests = new Mapper(); - var responses = new Mapper(); - var processedResponses = new Mapper(); - var message2Key = {}; - function storeResponse(message, id, dest) { - var response = { - message: message, - timeout: setTimeout(function () { - responses.remove(id, dest); - }, response_timeout) - }; - responses.set(response, id, dest); - } - ; - function storeProcessedResponse(ack, from) { - var timeout = setTimeout(function () { - processedResponses.remove(ack, from); - }, duplicates_timeout); - processedResponses.set(timeout, ack, from); - } - ; - function RpcRequest(method, params, id, from, transport) { - RpcNotification.call(this, method, params); - this.getTransport = function () { - return transport; - }; - this.setTransport = function (value) { - transport = unifyTransport(value); - }; - if (!defineProperty_IE8) - Object.defineProperty(this, 'transport', { - get: this.getTransport.bind(this), - set: this.setTransport.bind(this) - }); - var response = responses.get(id, from); - if (!(transport || self.getTransport())) { - if (defineProperty_IE8) - this.duplicated = Boolean(response); - else - Object.defineProperty(this, 'duplicated', { - value: Boolean(response) - }); - } - var responseMethod = responseMethods[method]; - this.pack = packer.pack.bind(packer, this, id); - this.reply = function (error, result, transport) { - if (error instanceof Function || error && error.send instanceof Function) { - if (result != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = error; - result = null; - error = undefined; - } - else if (result instanceof Function - || result && result.send instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - transport = result; - result = null; - } - ; - transport = unifyTransport(transport); - if (response) - clearTimeout(response.timeout); - if (from != undefined) { - if (error) - error.dest = from; - if (result) - result.dest = from; - } - ; - var message; - if (error || result != undefined) { - if (self.peerID != undefined) { - if (error) - error.from = self.peerID; - else - result.from = self.peerID; - } - if (responseMethod) { - if (responseMethod.error == undefined && error) - message = - { - error: error - }; - else { - var method = error - ? responseMethod.error - : responseMethod.response; - message = - { - method: method, - params: error || result - }; - } - } - else - message = - { - error: error, - result: result - }; - message = packer.pack(message, id); - } - else if (response) - message = response.message; - else - message = packer.pack({ result: null }, id); - storeResponse(message, id, from); - transport = transport || this.getTransport() || self.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - } - ; - inherits(RpcRequest, RpcNotification); - function cancel(message) { - var key = message2Key[message]; - if (!key) - return; - delete message2Key[message]; - var request = requests.pop(key.id, key.dest); - if (!request) - return; - clearTimeout(request.timeout); - storeProcessedResponse(key.id, key.dest); - } - ; - this.cancel = function (message) { - if (message) - return cancel(message); - for (var message in message2Key) - cancel(message); - }; - this.close = function () { - var transport = this.getTransport(); - if (transport && transport.close) - transport.close(4003, "Cancel request"); - this.cancel(); - processedResponses.forEach(clearTimeout); - responses.forEach(function (response) { - clearTimeout(response.timeout); - }); - }; - this.encode = function (method, params, dest, transport, callback) { - if (params instanceof Function) { - if (dest != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = params; - transport = undefined; - dest = undefined; - params = undefined; - } - else if (dest instanceof Function) { - if (transport != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = dest; - transport = undefined; - dest = undefined; - } - else if (transport instanceof Function) { - if (callback != undefined) - throw new SyntaxError("There can't be parameters after callback"); - callback = transport; - transport = undefined; - } - ; - if (self.peerID != undefined) { - params = params || {}; - params.from = self.peerID; - } - ; - if (dest != undefined) { - params = params || {}; - params.dest = dest; - } - ; - var message = { - method: method, - params: params - }; - if (callback) { - var id = requestID++; - var retried = 0; - message = packer.pack(message, id); - function dispatchCallback(error, result) { - self.cancel(message); - callback(error, result); - } - ; - var request = { - message: message, - callback: dispatchCallback, - responseMethods: responseMethods[method] || {} - }; - var encode_transport = unifyTransport(transport); - function sendRequest(transport) { - var rt = (method === 'ping' ? ping_request_timeout : request_timeout); - request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); - message2Key[message] = { id: id, dest: dest }; - requests.set(request, id, dest); - transport = transport || encode_transport || self.getTransport(); - if (transport) - return transport.send(message); - return message; - } - ; - function retry(transport) { - transport = unifyTransport(transport); - console.warn(retried + ' retry for request message:', message); - var timeout = processedResponses.pop(id, dest); - clearTimeout(timeout); - return sendRequest(transport); - } - ; - function timeout() { - if (retried < max_retries) - return retry(transport); - var error = new Error('Request has timed out'); - error.request = message; - error.retry = retry; - dispatchCallback(error); - } - ; - return sendRequest(transport); - } - ; - message = packer.pack(message); - transport = transport || this.getTransport(); - if (transport) - return transport.send(message); - return message; - }; - this.decode = function (message, transport) { - if (!message) - throw new TypeError("Message is not defined"); - try { - message = packer.unpack(message); - } - catch (e) { - return console.debug(e, message); - } - ; - var id = message.id; - var ack = message.ack; - var method = message.method; - var params = message.params || {}; - var from = params.from; - var dest = params.dest; - if (self.peerID != undefined && from == self.peerID) - return; - if (id == undefined && ack == undefined) { - var notification = new RpcNotification(method, params); - if (self.emit('request', notification)) - return; - return notification; - } - ; - function processRequest() { - transport = unifyTransport(transport) || self.getTransport(); - if (transport) { - var response = responses.get(id, from); - if (response) - return transport.send(response.message); - } - ; - var idAck = (id != undefined) ? id : ack; - var request = new RpcRequest(method, params, idAck, from, transport); - if (self.emit('request', request)) - return; - return request; - } - ; - function processResponse(request, error, result) { - request.callback(error, result); - } - ; - function duplicatedResponse(timeout) { - console.warn("Response already processed", message); - clearTimeout(timeout); - storeProcessedResponse(ack, from); - } - ; - if (method) { - if (dest == undefined || dest == self.peerID) { - var request = requests.get(ack, from); - if (request) { - var responseMethods = request.responseMethods; - if (method == responseMethods.error) - return processResponse(request, params); - if (method == responseMethods.response) - return processResponse(request, null, params); - return processRequest(); - } - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - } - return processRequest(); - } - ; - var error = message.error; - var result = message.result; - if (error && error.dest && error.dest != self.peerID) - return; - if (result && result.dest && result.dest != self.peerID) - return; - var request = requests.get(ack, from); - if (!request) { - var processed = processedResponses.get(ack, from); - if (processed) - return duplicatedResponse(processed); - return console.warn("No callback was defined for this message", message); - } - ; - processResponse(request, error, result); - }; -} -; -inherits(RpcBuilder, EventEmitter); -RpcBuilder.RpcNotification = RpcNotification; -module.exports = RpcBuilder; -var clients = require('./clients'); -var transports = require('./clients/transports'); -RpcBuilder.clients = clients; -RpcBuilder.clients.transports = transports; -RpcBuilder.packers = packers; - -},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ -function pack(message, id) { - var result = { - jsonrpc: "2.0" - }; - if (message.method) { - result.method = message.method; - if (message.params) - result.params = message.params; - if (id != undefined) - result.id = id; - } - else if (id != undefined) { - if (message.error) { - if (message.result !== undefined) - throw new TypeError("Both result and error are defined"); - result.error = message.error; - } - else if (message.result !== undefined) - result.result = message.result; - else - throw new TypeError("No result or error is defined"); - result.id = id; - } - ; - return JSON.stringify(result); -} -; -function unpack(message) { - var result = message; - if (typeof message === 'string' || message instanceof String) { - result = JSON.parse(message); - } - var version = result.jsonrpc; - if (version !== '2.0') - throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); - if (result.method == undefined) { - if (result.id == undefined) - throw new TypeError("Invalid message: " + message); - var result_defined = result.result !== undefined; - var error_defined = result.error !== undefined; - if (result_defined && error_defined) - throw new TypeError("Both result and error are defined: " + message); - if (!result_defined && !error_defined) - throw new TypeError("No result or error is defined: " + message); - result.ack = result.id; - delete result.id; - } - return result; -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],48:[function(require,module,exports){ -function pack(message) { - throw new TypeError("Not yet implemented"); -} -; -function unpack(message) { - throw new TypeError("Not yet implemented"); -} -; -exports.pack = pack; -exports.unpack = unpack; - -},{}],49:[function(require,module,exports){ -var JsonRPC = require('./JsonRPC'); -var XmlRPC = require('./XmlRPC'); -exports.JsonRPC = JsonRPC; -exports.XmlRPC = XmlRPC; - -},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ -window.getScreenId = function (firefoxString, callback, custom_parameter) { - if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { - callback({ - video: true - }); - return; - } - if (!!navigator.mozGetUserMedia) { - callback(null, 'firefox', { - video: { - mozMediaSource: firefoxString, - mediaSource: firefoxString - } - }); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeMediaSourceId) { - if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { - callback('permission-denied'); - } - else { - callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); - } - window.removeEventListener('message', onIFrameCallback); - } - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); - window.removeEventListener('message', onIFrameCallback); - } - } - if (!custom_parameter) { - setTimeout(postGetSourceIdMessage, 100); - } - else { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - } -}; -function getScreenConstraints(error, sourceId, canRequestAudioTrack) { - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, - maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 - }, - optional: [] - } - }; - if (!!canRequestAudioTrack) { - screen_constraints.audio = { - mandatory: { - chromeMediaSource: error ? 'screen' : 'desktop', - }, - optional: [] - }; - } - if (sourceId) { - screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; - if (screen_constraints.audio && screen_constraints.audio.mandatory) { - screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; - } - } - return screen_constraints; -} -function postGetSourceIdMessage(custom_parameter) { - if (!iframe) { - loadIFrame(function () { - postGetSourceIdMessage(custom_parameter); - }); - return; - } - if (!iframe.isLoaded) { - setTimeout(function () { - postGetSourceIdMessage(custom_parameter); - }, 100); - return; - } - if (!custom_parameter) { - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - else if (!!custom_parameter.forEach) { - iframe.contentWindow.postMessage({ - captureCustomSourceId: custom_parameter - }, '*'); - } - else { - iframe.contentWindow.postMessage({ - captureSourceIdWithAudio: true - }, '*'); - } -} -var iframe; -window.getScreenConstraints = function (callback) { - loadIFrame(function () { - getScreenId(function (error, sourceId, screen_constraints) { - if (!screen_constraints) { - screen_constraints = { - video: true - }; - } - callback(error, screen_constraints.video); - }); - }); -}; -function loadIFrame(loadCallback) { - if (iframe) { - loadCallback(); - return; - } - iframe = document.createElement('iframe'); - iframe.onload = function () { - iframe.isLoaded = true; - loadCallback(); - }; - iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); -} -window.getChromeExtensionStatus = function (callback) { - if (!!navigator.mozGetUserMedia) { - callback('installed-enabled'); - return; - } - window.addEventListener('message', onIFrameCallback); - function onIFrameCallback(event) { - if (!event.data) - return; - if (event.data.chromeExtensionStatus) { - callback(event.data.chromeExtensionStatus); - window.removeEventListener('message', onIFrameCallback); - } - } - setTimeout(postGetChromeExtensionStatusMessage, 100); -}; -function postGetChromeExtensionStatusMessage() { - if (!iframe) { - loadIFrame(postGetChromeExtensionStatusMessage); - return; - } - if (!iframe.isLoaded) { - setTimeout(postGetChromeExtensionStatusMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - getChromeExtensionStatus: true - }, '*'); -} -exports.getScreenId = getScreenId; - -},{}],51:[function(require,module,exports){ -var chromeMediaSource = 'screen'; -var sourceId; -var screenCallback; -var isFirefox = typeof window.InstallTrigger !== 'undefined'; -var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; -var isChrome = !!window.chrome && !isOpera; -window.addEventListener('message', function (event) { - if (event.origin != window.location.origin) { - return; - } - onMessageCallback(event.data); -}); -function onMessageCallback(data) { - if (data == 'PermissionDeniedError') { - if (screenCallback) - return screenCallback('PermissionDeniedError'); - else - throw new Error('PermissionDeniedError'); - } - if (data == 'rtcmulticonnection-extension-loaded') { - chromeMediaSource = 'desktop'; - } - if (data.sourceId && screenCallback) { - screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); - } -} -function isChromeExtensionAvailable(callback) { - if (!callback) - return; - if (chromeMediaSource == 'desktop') - return callback(true); - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback(false); - } - else - callback(true); - }, 2000); -} -function getSourceId(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('get-sourceId', '*'); -} -function getCustomSourceId(arr, callback) { - if (!arr || !arr.forEach) - throw '"arr" parameter is mandatory and it must be an array.'; - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage({ - 'get-custom-sourceId': arr - }, '*'); -} -function getSourceIdWithAudio(callback) { - if (!callback) - throw '"callback" parameter is mandatory.'; - if (sourceId) - return callback(sourceId); - screenCallback = callback; - window.postMessage('audio-plus-tab', '*'); -} -function getChromeExtensionStatus(extensionid, callback) { - if (isFirefox) - return callback('not-chrome'); - if (arguments.length != 2) { - callback = extensionid; - extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; - } - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function () { - chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function () { - if (chromeMediaSource == 'screen') { - callback('installed-disabled'); - } - else - callback('installed-enabled'); - }, 2000); - }; - image.onerror = function () { - callback('not-installed'); - }; -} -function getScreenConstraintsWithAudio(callback) { - getScreenConstraints(callback, true); -} -function getScreenConstraints(callback, captureSourceIdWithAudio) { - sourceId = ''; - var firefoxScreenConstraints = { - mozMediaSource: 'window', - mediaSource: 'window' - }; - if (isFirefox) - return callback(null, firefoxScreenConstraints); - var screen_constraints = { - mandatory: { - chromeMediaSource: chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - }; - if (chromeMediaSource == 'desktop' && !sourceId) { - if (captureSourceIdWithAudio) { - getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - if (canRequestAudioTrack) { - screen_constraints.canRequestAudioTrack = true; - } - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - else { - getSourceId(function (sourceId) { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); - }); - } - return; - } - if (chromeMediaSource == 'desktop') { - screen_constraints.mandatory.chromeMediaSourceId = sourceId; - } - callback(null, screen_constraints); -} -exports.getScreenConstraints = getScreenConstraints; -exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; -exports.isChromeExtensionAvailable = isChromeExtensionAvailable; -exports.getChromeExtensionStatus = getChromeExtensionStatus; -exports.getSourceId = getSourceId; - -},{}],52:[function(require,module,exports){ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var freeice = require("freeice"); -var uuid = require("uuid"); -var platform = require("platform"); -var WebRtcPeer = (function () { - function WebRtcPeer(configuration) { - var _this = this; - this.configuration = configuration; - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - this.iceCandidateList = []; - this.candidategatheringdone = false; - this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); - this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); - this.id = !!configuration.id ? configuration.id : uuid.v4(); - this.pc.onicecandidate = function (event) { - if (!!event.candidate) { - var candidate = event.candidate; - if (candidate) { - _this.localCandidatesQueue.push({ candidate: candidate.candidate }); - _this.candidategatheringdone = false; - _this.configuration.onicecandidate(event.candidate); - } - else if (!_this.candidategatheringdone) { - _this.candidategatheringdone = true; - } - } - }; - this.pc.onsignalingstatechange = function () { - if (_this.pc.signalingState === 'stable') { - while (_this.iceCandidateList.length > 0) { - _this.pc.addIceCandidate(_this.iceCandidateList.shift()); - } - } - }; - this.start(); - } - WebRtcPeer.prototype.start = function () { - var _this = this; - return new Promise(function (resolve, reject) { - if (_this.pc.signalingState === 'closed') { - reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); - } - if (!!_this.configuration.mediaStream) { - if (platform['isIonicIos']) { - var pc2 = _this.pc; - pc2.addStream(_this.configuration.mediaStream); - } - else { - for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { - var track = _a[_i]; - _this.pc.addTrack(track, _this.configuration.mediaStream); - } - } - resolve(); - } - }); - }; - WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { - console.debug('Disposing WebRtcPeer'); - try { - if (this.pc) { - if (this.pc.signalingState === 'closed') { - return; - } - this.remoteCandidatesQueue = []; - this.localCandidatesQueue = []; - if (platform['isIonicIos']) { - var pc1 = this.pc; - for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { - var sender = _a[_i]; - if (!videoSourceIsMediaStreamTrack) { - sender.stop(); - } - pc1.removeStream(sender); - } - for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { - var receiver = _c[_b]; - if (!!receiver.track) { - receiver.stop(); - } - } - } - else { - for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { - var sender = _e[_d]; - if (!videoSourceIsMediaStreamTrack) { - if (!!sender.track) { - sender.track.stop(); - } - } - this.pc.removeTrack(sender); - } - for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { - var receiver = _g[_f]; - if (!!receiver.track) { - receiver.track.stop(); - } - } - } - this.pc.close(); - } - } - catch (err) { - console.warn('Exception disposing webrtc peer ' + err); - } - }; - WebRtcPeer.prototype.generateOffer = function () { - var _this = this; - return new Promise(function (resolve, reject) { - var offerAudio, offerVideo = true; - if (!!_this.configuration.mediaConstraints) { - offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? - _this.configuration.mediaConstraints.audio : true; - offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? - _this.configuration.mediaConstraints.video : true; - } - var constraints = { - offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), - offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) - }; - console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { - if (offerAudio) { - _this.pc.addTransceiver('audio', { - direction: _this.configuration.mode, - }); - } - if (offerVideo) { - _this.pc.addTransceiver('video', { - direction: _this.configuration.mode, - }); - } - _this.pc - .createOffer() - .then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - else { - _this.pc.createOffer(constraints).then(function (offer) { - console.debug('Created SDP offer'); - return _this.pc.setLocalDescription(offer); - }) - .then(function () { - var localDescription = _this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } - else { - reject('Local description is not defined'); - } - }) - .catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) { - var _this = this; - return new Promise(function (resolve, reject) { - var answer = { - type: 'answer', - sdp: sdpAnswer - }; - console.debug('SDP answer received, setting remote description'); - if (_this.pc.signalingState === 'closed') { - reject('RTCPeerConnection is closed'); - } - if (needsTimeoutOnProcessAswer && platform['isIonicIos']) { - setTimeout(function () { - console.info('setRemoteDescription run after timout for iOS device'); - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - }, 250); - } - else { - _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - }); - }; - WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { - var _this = this; - return new Promise(function (resolve, reject) { - console.debug('Remote ICE candidate received', iceCandidate); - _this.remoteCandidatesQueue.push(iceCandidate); - switch (_this.pc.signalingState) { - case 'closed': - reject(new Error('PeerConnection object is closed')); - break; - case 'stable': - if (!!_this.pc.remoteDescription) { - _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); - } - else { - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - break; - default: - _this.iceCandidateList.push(iceCandidate); - resolve(); - } - }); - }; - return WebRtcPeer; -}()); -exports.WebRtcPeer = WebRtcPeer; -var WebRtcPeerRecvonly = (function (_super) { - __extends(WebRtcPeerRecvonly, _super); - function WebRtcPeerRecvonly(configuration) { - var _this = this; - configuration.mode = 'recvonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerRecvonly; -}(WebRtcPeer)); -exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; -var WebRtcPeerSendonly = (function (_super) { - __extends(WebRtcPeerSendonly, _super); - function WebRtcPeerSendonly(configuration) { - var _this = this; - configuration.mode = 'sendonly'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendonly; -}(WebRtcPeer)); -exports.WebRtcPeerSendonly = WebRtcPeerSendonly; -var WebRtcPeerSendrecv = (function (_super) { - __extends(WebRtcPeerSendrecv, _super); - function WebRtcPeerSendrecv(configuration) { - var _this = this; - configuration.mode = 'sendrecv'; - _this = _super.call(this, configuration) || this; - return _this; - } - return WebRtcPeerSendrecv; -}(WebRtcPeer)); -exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; - -},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var platform = require("platform"); -var WebRtcStats = (function () { - function WebRtcStats(stream) { - this.stream = stream; - this.webRtcStatsEnabled = false; - this.statsInterval = 1; - this.stats = { - inbound: { - audio: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0 - }, - video: { - bytesReceived: 0, - packetsReceived: 0, - packetsLost: 0, - framesDecoded: 0, - nackCount: 0 - } - }, - outbound: { - audio: { - bytesSent: 0, - packetsSent: 0, - }, - video: { - bytesSent: 0, - packetsSent: 0, - framesEncoded: 0, - nackCount: 0 - } - } - }; - } - WebRtcStats.prototype.isEnabled = function () { - return this.webRtcStatsEnabled; - }; - WebRtcStats.prototype.initWebRtcStats = function () { - var _this = this; - var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); - if (!!elastestInstrumentation) { - console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - this.webRtcStatsEnabled = true; - var instrumentation_1 = JSON.parse(elastestInstrumentation); - this.statsInterval = instrumentation_1.webrtc.interval; - console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); - this.webRtcStatsIntervalId = setInterval(function () { - _this.sendStatsToHttpEndpoint(instrumentation_1); - }, this.statsInterval * 1000); - return; - } - console.debug('WebRtc stats not enabled'); - }; - WebRtcStats.prototype.stopWebRtcStats = function () { - if (this.webRtcStatsEnabled) { - clearInterval(this.webRtcStatsIntervalId); - console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); - } - }; - WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { - var _this = this; - return new Promise(function (resolve, reject) { - _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { - if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; - var localCandidates = {}; - var remoteCandidates = {}; - for (var key in stats) { - var stat = stats[key]; - if (stat.type === 'localcandidate') { - localCandidates[stat.id] = stat; - } - else if (stat.type === 'remotecandidate') { - remoteCandidates[stat.id] = stat; - } - else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { - googCandidatePair = stat; - localCandidateId = stat.localCandidateId; - remoteCandidateId = stat.remoteCandidateId; - } - } - var finalLocalCandidate_1 = localCandidates[localCandidateId]; - if (!!finalLocalCandidate_1) { - var candList = _this.stream.getLocalIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); - }); - finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; - } - else { - finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; - } - var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; - if (!!finalRemoteCandidate_1) { - var candList = _this.stream.getRemoteIceCandidateList(); - var cand = candList.filter(function (c) { - return (!!c.candidate && - c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && - c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); - }); - finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; - } - else { - finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; - } - resolve({ - googCandidatePair: googCandidatePair, - localCandidate: finalLocalCandidate_1, - remoteCandidate: finalRemoteCandidate_1 - }); - } - else { - reject('Selected ICE candidate info only available for Chrome'); - } - }, function (error) { - reject(error); - }); - }); - }; - WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { - var _this = this; - var sendPost = function (json) { - var http = new XMLHttpRequest(); - var url = instrumentation.webrtc.httpEndpoint; - http.open('POST', url, true); - http.setRequestHeader('Content-type', 'application/json'); - http.onreadystatechange = function () { - if (http.readyState === 4 && http.status === 200) { - console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); - } - }; - http.send(json); - }; - var f = function (stats) { - if (platform.name.indexOf('Firefox') !== -1) { - stats.forEach(function (stat) { - var json = {}; - if ((stat.type === 'inbound-rtp') && - (stat.nackCount !== null && - stat.isRemote === false && - stat.id.startsWith('inbound') && - stat.remoteId.startsWith('inbound'))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var jit = stat.jitter * 1000; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: jit, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.nackCount; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ((stat.type === 'outbound-rtp') && - (stat.isRemote === false && - stat.id.toLowerCase().includes('outbound'))) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - }); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { - var key = _a[_i]; - var stat = stats[key]; - if (stat.type === 'ssrc') { - var json = {}; - if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || - (stat.mediaType === 'video' && 'qpSum' in stat))) { - var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, - jitter: stat.googJitterBufferMs, - packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, - packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval - }; - var units = { - bytesReceived: 'bytes', - jitter: 'ms', - packetsReceived: 'packets', - packetsLost: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; - metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; - units['framesDecoded'] = 'frames'; - units['nackCount'] = 'packets'; - _this.stats.inbound.video.framesDecoded = stat.framesDecoded; - _this.stats.inbound.video.nackCount = stat.googNacksSent; - } - _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; - _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; - _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - else if ('bytesSent' in stat) { - var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; - var metrics = { - bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, - packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval - }; - var units = { - bytesSent: 'bytes', - packetsSent: 'packets' - }; - if (stat.mediaType === 'video') { - metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; - units['framesEncoded'] = 'frames'; - _this.stats.outbound.video.framesEncoded = stat.framesEncoded; - } - _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; - _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; - json = { - '@timestamp': new Date(stat.timestamp).toISOString(), - 'exec': instrumentation.exec, - 'component': instrumentation.component, - 'stream': 'webRtc', - 'et_type': metricId, - 'stream_type': 'composed_metrics', - 'units': units - }; - json[metricId] = metrics; - sendPost(JSON.stringify(json)); - } - } - } - } - }; - this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); - }; - WebRtcStats.prototype.standardizeReport = function (response) { - console.log(response); - var standardReport = {}; - if (platform.name.indexOf('Firefox') !== -1) { - Object.keys(response).forEach(function (key) { - console.log(response[key]); - }); - return response; - } - response.result().forEach(function (report) { - var standardStats = { - id: report.id, - timestamp: report.timestamp, - type: report.type - }; - report.names().forEach(function (name) { - standardStats[name] = report.stat(name); - }); - standardReport[standardStats.id] = standardStats; - }); - return standardReport; - }; - WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { - var _this = this; - if (platform.name.indexOf('Firefox') !== -1) { - return pc.getStats(null).then(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }).catch(failureCb); - } - else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { - return pc.getStats(function (response) { - var report = _this.standardizeReport(response); - successCb(report); - }, null, failureCb); - } - }; - return WebRtcStats; -}()); -exports.WebRtcStats = WebRtcStats; - -},{"platform":8}]},{},[17]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0ZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlDQSxnREFBK0M7QUFFL0MsSUFBSSxNQUFNLEVBQUU7SUFDUixNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsbUJBQVEsQ0FBQztDQUNqQzs7Ozs7QUNjRCxtQ0FBa0M7QUFVbEM7SUF5Q0ksb0JBQW9CLE9BQWdCLEVBQUUsSUFBd0I7UUFBMUMsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQVZwQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBV2IsSUFBSSxHQUFHLEdBQUcsdUJBQXVCLENBQUM7UUFDbEMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO1lBRVIsR0FBRyxJQUFJLGdDQUFnQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1lBQ3hELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDbkMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzthQUM3QjtZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDZCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3hDO1NBQ0o7YUFBTTtZQUVILEdBQUcsSUFBSSxTQUFTLENBQUM7U0FDcEI7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFRRCxxQ0FBZ0IsR0FBaEIsVUFBaUIsU0FBMEI7UUFFdkMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLGVBQWU7WUFDbkYsSUFBSSxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVsQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEQsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQy9CLFNBQVMsRUFBRSxTQUFTLENBQUMsU0FBUztZQUM5QixNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDeEIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO1NBQ3pDLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtZQUNmLElBQUksS0FBSyxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsK0JBQStCO3NCQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDaEM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCxzQ0FBaUIsR0FBakIsVUFBa0IsT0FBOEI7UUFBaEQsaUJBd0JDO1FBcEJHLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQSxJQUFJO1lBQ2hCLElBQU0sYUFBYSxHQUF5QjtnQkFDeEMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsVUFBVSxFQUFFLEtBQUk7Z0JBQ2hCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM3QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7Z0JBQ3pCLGVBQWUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ3RGLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUzthQUNsRCxDQUFDO1lBQ0YsSUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztZQUV2RCxLQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLElBQUksQ0FBQywyQ0FBMkMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLDBEQUEwRCxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM5SyxDQUFDO0lBS0QsOEJBQVMsR0FBVCxVQUFVLE1BQWM7UUFDcEIsTUFBTSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDekIsQ0FBQztJQUtELGlDQUFZLEdBQVosVUFBYSxRQUFnQjtRQUN6QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUtELDRCQUFPLEdBQVA7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO1NBQ3RCO1FBQ0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVMLGlCQUFDO0FBQUQsQ0E1SUEsQUE0SUMsSUFBQTtBQTVJWSxnQ0FBVTs7Ozs7QUNUdkIsb0dBQW1HO0FBQ25HLHlFQUEyRjtBQVMzRjtJQTZDSSxnQkFBWSxJQUFZLEVBQUUsT0FBZTtRQVh6QyxhQUFRLEdBQXlDLEVBQUUsQ0FBQztRQVloRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUMzQixDQUFDO0lBU0QsMkJBQVUsR0FBVixVQUFXLE1BQWMsRUFBRSxNQUFjO1FBQXpDLGlCQXFDQztRQXBDRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFFLElBQUksWUFBWSxDQUFDO1lBQ2pCLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO2dCQUM1QixJQUFJO29CQUNBLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUN6QztnQkFBQyxPQUFPLEtBQUssRUFBRTtvQkFDWixJQUFNLFFBQVEsR0FBRyxtREFBbUQsQ0FBQztvQkFDckUsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDeEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUNwQjthQUNKO2lCQUFNO2dCQUNILFlBQVksR0FBVyxNQUFNLENBQUM7YUFDakM7WUFDRCxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNwQyxrQkFBa0IsRUFDbEIsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUNoRSxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkNBQTJDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3pGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUsdURBQXVELENBQUMsQ0FBQyxDQUFDO3FCQUNwSTt5QkFBTTt3QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdEYsSUFBTSxRQUFRLEdBQVMsTUFBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDOUQsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztvQkFDakYsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZMLEtBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNuTSxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBV0QsaUNBQWdCLEdBQWhCLFVBQWlCLFNBQWlCLEVBQUUsT0FBcUM7UUFBekUsaUJBc0JDO1FBckJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxHQUFHLFNBQVMsR0FBRyxhQUFhLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRyxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNwQyx3QkFBd0IsRUFDeEIsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsU0FBUyxXQUFBLEVBQUUsRUFDN0MsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLEtBQUssRUFBRTtvQkFDUCxPQUFPLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxHQUFHLFNBQVMsR0FBRyxhQUFhLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3hILElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUsMkRBQTJELENBQUMsQ0FBQyxDQUFDO3FCQUN4STt5QkFBTTt3QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO3FCQUFNO29CQUNILEtBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsT0FBTyxDQUFDO29CQUNuQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLFNBQVMsR0FBRyxrQ0FBa0MsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN4SCxPQUFPLEVBQUUsQ0FBQztpQkFDYjtZQUNMLENBQUMsQ0FDSixDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBVUQsb0NBQW1CLEdBQW5CLFVBQW9CLFNBQWlCO1FBQXJDLGlCQXNCQztRQXJCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDNUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDcEMsMkJBQTJCLEVBQzNCLEVBQUUsUUFBUSxFQUFFLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsV0FBQSxFQUFFLEVBQzdDLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxLQUFLLEVBQUU7b0JBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMxSCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUFFO3dCQUNwQixNQUFNLENBQUMsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDBCQUEwQixFQUFFLDJEQUEyRCxDQUFDLENBQUMsQ0FBQztxQkFDeEk7eUJBQU07d0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUNqQjtpQkFDSjtxQkFBTTtvQkFDSCxPQUFPLEtBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ2hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsU0FBUyxHQUFHLGtDQUFrQyxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3hILE9BQU8sRUFBRSxDQUFDO2lCQUNiO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTCxhQUFDO0FBQUQsQ0FqS0EsQUFpS0MsSUFBQTtBQWpLWSx3QkFBTTs7Ozs7QUNYbkIsbUZBQWtGO0FBQ2xGLG1DQUFzQztBQWdCdEM7SUFlSSx1QkFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFUMUIsV0FBTSxHQUFVLEVBQUUsQ0FBQztRQVV2QixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUM7UUFDNUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxjQUFjLENBQUM7UUFDMUUsSUFBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQU9ELDhCQUFNLEdBQU47UUFBQSxpQkFxRUM7UUFwRUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRS9CLElBQUk7Z0JBRUEsSUFBSSxPQUFPLGFBQWEsS0FBSyxXQUFXLEVBQUU7b0JBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkdBQTZHLENBQUMsQ0FBQztvQkFDN0gsTUFBTSxDQUFDLEtBQUssQ0FBQyw2R0FBNkcsQ0FBQyxDQUFDLENBQUM7aUJBQ2hJO2dCQUNELElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxLQUFLLEVBQUU7b0JBQ3pDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUZBQXlGLEdBQUcsS0FBSSxDQUFDLEtBQUssR0FBRyx3RUFBd0UsQ0FBQyxDQUFDLENBQUM7aUJBQ3BNO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsbUJBQW1CLEdBQUcsS0FBSSxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsQ0FBQztnQkFHM0gsSUFBSSxPQUFPLGFBQWEsQ0FBQyxlQUFlLEtBQUssVUFBVSxFQUFFO29CQUNyRCxJQUFJLE9BQU8sU0FBQSxDQUFDO29CQUNaLElBQUksYUFBYSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFO3dCQUN4RCxPQUFPLEdBQUcsRUFBRSxRQUFRLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQztxQkFDbkQ7eUJBQU0sSUFBSSxhQUFhLENBQUMsZUFBZSxDQUFDLHdCQUF3QixDQUFDLEVBQUU7d0JBQ2hFLE9BQU8sR0FBRyxFQUFFLFFBQVEsRUFBRSx3QkFBd0IsRUFBRSxDQUFDO3FCQUNwRDt5QkFBTSxJQUFJLGFBQWEsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQUMsRUFBRTt3QkFDL0QsT0FBTyxHQUFHLEVBQUUsUUFBUSxFQUFFLHVCQUF1QixFQUFFLENBQUM7cUJBQ25EO29CQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUNsRCxLQUFJLENBQUMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7aUJBQ2pGO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsb0VBQW9FLENBQUMsQ0FBQztvQkFDbkYsS0FBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7aUJBQ3hFO2dCQUVELEtBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBRWhDO1lBQUMsT0FBTyxHQUFHLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2Y7WUFFRCxLQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsR0FBRyxVQUFDLENBQUM7Z0JBQ25DLEtBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRyxVQUFDLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUMsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEdBQUc7Z0JBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0JBQStCLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDbEYsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUc7Z0JBQ3hCLEtBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRztnQkFDekIsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNqRixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsR0FBRztnQkFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNsRixDQUFDLENBQUM7WUFFRixLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxVQUFDLENBQUM7Z0JBQzdCLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxTQUFTLENBQUM7WUFDMUMsT0FBTyxFQUFFLENBQUM7UUFFZCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFPRCw0QkFBSSxHQUFKO1FBQUEsaUJBZUM7UUFkRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSTtnQkFDQSxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsS0FBSyxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO29CQUN2RixNQUFNLENBQUMsS0FBSyxDQUFDLHlHQUF5RyxHQUFHLEtBQUksQ0FBQyxLQUFLLEdBQUcsNENBQTRDLENBQUMsQ0FBQyxDQUFDO2lCQUN4TDtnQkFDRCxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRztvQkFDeEIsS0FBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUNyQixPQUFPLEVBQUUsQ0FBQztnQkFDZCxDQUFDLENBQUM7Z0JBQ0YsS0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUM3QjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNiO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBT0QsNkJBQUssR0FBTDtRQUFBLGlCQVlDO1FBWEcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUk7Z0JBQ0EsSUFBSSxLQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsRUFBRTtvQkFDN0MsTUFBTSxDQUFDLEtBQUssQ0FBQyw0RkFBNEYsR0FBRyxLQUFJLENBQUMsS0FBSyxHQUFHLDBFQUEwRSxDQUFDLENBQUMsQ0FBQztpQkFDek07Z0JBQ0QsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDM0IsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxNQUFNLENBQUM7YUFDMUM7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDWixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDakI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFNRCw4QkFBTSxHQUFOO1FBQUEsaUJBWUM7UUFYRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSTtnQkFDQSxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsTUFBTSxFQUFFO29CQUMxQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBGQUEwRixHQUFHLEtBQUksQ0FBQyxLQUFLLEdBQUcsNENBQTRDLENBQUMsQ0FBQyxDQUFDO2lCQUN6SztnQkFDRCxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM1QixLQUFJLENBQUMsS0FBSyxHQUFHLHVDQUFrQixDQUFDLFNBQVMsQ0FBQzthQUM3QztZQUFDLE9BQU8sS0FBSyxFQUFFO2dCQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNqQjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU1ELCtCQUFPLEdBQVAsVUFBUSxhQUFhO1FBRWpCLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7WUFDNUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2RkFBNkYsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLDJDQUEyQyxDQUFDLENBQUMsQ0FBQztTQUMzSztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUVsQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQzVCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztTQUN6RDtRQUVELElBQUksT0FBTyxhQUFhLEtBQUssUUFBUSxFQUFFO1lBQ25DLElBQU0sZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRSxJQUFJLGdCQUFnQixFQUFFO2dCQUNsQixJQUFJLENBQUMsWUFBWSxHQUFHLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDdkU7U0FDSjthQUFNO1lBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNwRTtRQUVELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFFN0MsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLENBQUM7SUFNRCw2QkFBSyxHQUFMO1FBQUEsaUJBWUM7UUFYRyxJQUFNLENBQUMsR0FBRztZQUNOLE9BQU8sS0FBSSxDQUFDLElBQUksQ0FBQztZQUNqQixLQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNqQixPQUFPLEtBQUksQ0FBQyxhQUFhLENBQUM7WUFDMUIsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxLQUFLLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLE1BQU0sRUFBRTtZQUN6RixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQU0sT0FBQSxDQUFDLEVBQUUsRUFBSCxDQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsY0FBTSxPQUFBLENBQUMsRUFBRSxFQUFILENBQUcsQ0FBQyxDQUFDO1NBQ2hEO2FBQU07WUFDSCxDQUFDLEVBQUUsQ0FBQztTQUNQO0lBQ0wsQ0FBQztJQU1ELGdDQUFRLEdBQVI7UUFDSSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsOEZBQThGLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRywyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7U0FDNUs7YUFBTTtZQUNILElBQU0sQ0FBQyxHQUFzQixRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3pELENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztZQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU3QixJQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7WUFDYixDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDO1lBQy9CLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNWLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hDO0lBQ0wsQ0FBQztJQUtELCtCQUFPLEdBQVA7UUFDSSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQyxDQUFDO1NBQ3pFO2FBQU07WUFDSCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDcEI7SUFDTCxDQUFDO0lBYUQsc0NBQWMsR0FBZCxVQUFlLFFBQWdCLEVBQUUsT0FBYTtRQUE5QyxpQkEyQkM7UUExQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0dBQW9HLEdBQUcsS0FBSSxDQUFDLEtBQUssR0FBRywyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7YUFDbEw7aUJBQU07Z0JBQ0gsSUFBTSxNQUFJLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbEMsTUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVsQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtvQkFDN0IsS0FBa0IsVUFBb0IsRUFBcEIsS0FBQSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFwQixjQUFvQixFQUFwQixJQUFvQixFQUFFO3dCQUFuQyxJQUFNLEdBQUcsU0FBQTt3QkFDVixNQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUM1QztpQkFDSjtnQkFFRCxNQUFJLENBQUMsa0JBQWtCLEdBQUc7b0JBQ3RCLElBQUksTUFBSSxDQUFDLFVBQVUsS0FBSyxDQUFDLEVBQUU7d0JBQ3ZCLElBQUksTUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFOzRCQUUxQyxPQUFPLENBQUMsTUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO3lCQUM5Qjs2QkFBTTs0QkFDSCxNQUFNLENBQUMsTUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUN2QjtxQkFDSjtnQkFDTCxDQUFDLENBQUM7Z0JBQ0YsTUFBSSxDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFhRCw2Q0FBcUIsR0FBckIsVUFBc0IsUUFBZ0IsRUFBRSxPQUFhO1FBQXJELGlCQStCQztRQTlCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxLQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFFBQVEsRUFBRTtnQkFDNUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyR0FBMkcsR0FBRyxLQUFJLENBQUMsS0FBSyxHQUFHLDJDQUEyQyxDQUFDLENBQUMsQ0FBQzthQUN6TDtpQkFBTTtnQkFDSCxJQUFNLE1BQUksR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNsQyxNQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRWxDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO29CQUM3QixLQUFrQixVQUFvQixFQUFwQixLQUFBLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQXBCLGNBQW9CLEVBQXBCLElBQW9CLEVBQUU7d0JBQW5DLElBQU0sR0FBRyxTQUFBO3dCQUNWLE1BQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQzVDO2lCQUNKO2dCQUVELElBQU0sUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQztnQkFFdEQsTUFBSSxDQUFDLGtCQUFrQixHQUFHO29CQUN0QixJQUFJLE1BQUksQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFO3dCQUN2QixJQUFJLE1BQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTs0QkFFMUMsT0FBTyxDQUFDLE1BQUksQ0FBQyxZQUFZLENBQUMsQ0FBQzt5QkFDOUI7NkJBQU07NEJBQ0gsTUFBTSxDQUFDLE1BQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDdkI7cUJBQ0o7Z0JBQ0wsQ0FBQyxDQUFDO2dCQUVGLE1BQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDdkI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLTyxxQ0FBYSxHQUFyQjtRQUNJLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFL0UsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFFakIsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxRQUFRLENBQUM7SUFDN0MsQ0FBQztJQUVMLG9CQUFDO0FBQUQsQ0FsVkEsQUFrVkMsSUFBQTtBQWxWWSxzQ0FBYTs7Ozs7QUNsQjFCLGlEQUFnRDtBQUNoRCx5Q0FBd0M7QUFDeEMscUNBQW9DO0FBR3BDLG9HQUFtRztBQUluRyx5RUFBMkY7QUFDM0YsNkVBQTRFO0FBSTVFLDJGQUE2RjtBQUM3RixrRkFBb0Y7QUFFcEYsbURBQXNEO0FBQ3RELDZFQUFnRjtBQUNoRixtQ0FBc0M7QUFDdEMsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sS0FBSyxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsRUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUtsSSxJQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQU1sRDtJQXFERTtRQUFBLGlCQTRFQztRQXRIRCxlQUFVLEdBQWdCLEVBQUUsQ0FBQztRQVk3QixXQUFNLEdBQUcsRUFBRSxDQUFDO1FBSVosYUFBUSxHQUFHLEtBQUssQ0FBQztRQVlqQiwwQkFBcUIsR0FBa0MsRUFBRSxDQUFDO1FBSTFELHdCQUFtQixHQUFXLENBQUMsQ0FBQztRQVFoQyxPQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUdyQixJQUFJLENBQUMsY0FBYyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFFMUMsT0FBTyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRWpFLElBQUksUUFBUSxDQUFDLEVBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLFFBQVEsQ0FBQyxFQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUVsRSxNQUFPLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLEVBQUU7Z0JBQ2xELEtBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQUEsU0FBUztvQkFDL0IsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRTt3QkFFbkcsSUFBSSxVQUFRLEdBQUcsQ0FBQyxDQUFDO3dCQUVqQixJQUFNLFVBQVEsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7d0JBQ3hELElBQU0sV0FBUyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQzt3QkFFMUQsSUFBTSx1QkFBcUIsR0FBRzs0QkFDNUIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO2dDQUNqQyxJQUFJLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRTtvQ0FFMUIsT0FBTyxDQUFDO3dDQUNOLFFBQVEsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVU7d0NBQ25FLFNBQVMsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVc7cUNBQ3RFLENBQUMsQ0FBQztpQ0FDSjtxQ0FBTTtvQ0FJTCxJQUFNLGVBQWUsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO29DQUM1RixJQUFNLFFBQVEsR0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQ0FDbkosSUFBTSxTQUFTLEdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7b0NBQ3RKLE9BQU8sQ0FBQyxFQUFFLFFBQVEsVUFBQSxFQUFFLFNBQVMsV0FBQSxFQUFFLENBQUMsQ0FBQztpQ0FDbEM7NEJBQ0gsQ0FBQyxDQUFDLENBQUM7d0JBQ0wsQ0FBQyxDQUFDO3dCQUVGLElBQU0sbUJBQWlCLEdBQUcsV0FBVyxDQUFDOzRCQUNwQyx1QkFBcUIsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFBLGFBQWE7Z0NBQ3hDLGdDQUE4QixDQUFDLFVBQVEsRUFBRSxXQUFTLEVBQUUsYUFBYSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7NEJBQ3ZHLENBQUMsQ0FBQyxDQUFDO3dCQUNMLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFFUCxJQUFNLGdDQUE4QixHQUFHLFVBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUzs0QkFDOUUsVUFBUSxFQUFFLENBQUM7NEJBQ1gsSUFBSSxVQUFRLEdBQUcsRUFBRSxFQUFFO2dDQUNqQixZQUFZLENBQUMsbUJBQWlCLENBQUMsQ0FBQzs2QkFDakM7NEJBQ0QsSUFBSSxRQUFRLEtBQUssUUFBUSxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUU7Z0NBQ3BELFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxHQUFHO29DQUNqQyxLQUFLLEVBQUUsUUFBUSxJQUFJLENBQUM7b0NBQ3BCLE1BQU0sRUFBRSxTQUFTLElBQUksQ0FBQztpQ0FDdkIsQ0FBQztnQ0FDRixLQUFJLENBQUMsV0FBVyxDQUNkLHVCQUF1QixFQUN2QjtvQ0FDRSxRQUFRLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRO29DQUNuQyxRQUFRLEVBQUUsaUJBQWlCO29DQUMzQixRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQztvQ0FDMUQsTUFBTSxFQUFFLGVBQWU7aUNBQ3hCLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQ0FDZCxJQUFJLEtBQUssRUFBRTt3Q0FDVCxPQUFPLENBQUMsS0FBSyxDQUFDLDZDQUE2QyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FDQUNyRTt5Q0FBTTt3Q0FDTCxLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dDQUNoTyxTQUFTLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsSUFBSSx1REFBMEIsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztxQ0FDM047Z0NBQ0gsQ0FBQyxDQUFDLENBQUM7Z0NBQ0wsWUFBWSxDQUFDLG1CQUFpQixDQUFDLENBQUM7NkJBQ2pDO3dCQUNILENBQUMsQ0FBQztxQkFDSDtnQkFDSCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDO0lBTUQsOEJBQVcsR0FBWDtRQUNFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxpQkFBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBNEJELGdDQUFhLEdBQWIsVUFBYyxhQUFtQyxFQUFFLE1BQU8sRUFBRSxNQUFPO1FBRWpFLElBQUksVUFBK0IsQ0FBQztRQUVwQyxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLE1BQU0sS0FBSyxVQUFVLENBQUMsRUFBRTtZQUk5QyxVQUFVLEdBQXlCLE1BQU8sQ0FBQztZQUUzQyxVQUFVLEdBQUc7Z0JBQ1gsV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUNqRyxTQUFTLEVBQUUsQ0FBQyxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sVUFBVSxDQUFDLFNBQVMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMzTSxVQUFVLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTTtnQkFDcE0sTUFBTSxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RSxZQUFZLEVBQUUsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQy9GLFlBQVksRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDL0YsVUFBVSxFQUFFLENBQUMsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDOU0sV0FBVyxFQUFFLENBQUMsT0FBTyxVQUFVLENBQUMsV0FBVyxLQUFLLFdBQVcs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USxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdkI7YUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFOUYsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQUMsUUFBUTtnQkFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2QjtJQUNMLENBQUM7SUFFTCxrQkFBQztBQUFELENBcllBLEFBcVlDLElBQUE7QUFyWVksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjYgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjEyLjAuM1wiLFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNVwiLFxuICAgICAgICBcInV1aWRcIjogXCIzLjMuMlwiLFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjZcIlxuICAgIH0sXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIixcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIjE2LjIuM1wiLFxuICAgICAgICBcImdydW50XCI6IFwiMS4wLjRcIixcbiAgICAgICAgXCJncnVudC1hdXRvcHJlZml4ZXJcIjogXCIzLjAuNFwiLFxuICAgICAgICBcImdydW50LWNsaVwiOiBcIjEuMy4yXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIxLjAuMFwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIixcbiAgICAgICAgXCJncnVudC1zdHJpbmctcmVwbGFjZVwiOiBcIjEuMy4xXCIsXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsXG4gICAgICAgIFwidHNpZnlcIjogXCI0LjAuMVwiLFxuICAgICAgICBcInRzbGludFwiOiBcIjUuMTYuMFwiLFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjE0LjJcIixcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiMy40LjVcIixcbiAgICAgICAgXCJ1Z2xpZnktanNcIjogXCIzLjUuMTVcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjEwLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5cbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmdBdXRvIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8nO1xuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZyBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZyc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5wbGF0Zm9ybVsnaXNJb25pY0lvcyddID0gKHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGhvbmUnIHx8IHBsYXRmb3JtLnByb2R1Y3QgPT09ICdpUGFkJykgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSA9PT0gLTE7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBwYWNrYWdlSnNvbiA9IHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAoISFwdWJsaXNoZXIuc3RyZWFtICYmICEhcHVibGlzaGVyLnN0cmVhbS5oYXNWaWRlbyAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0pIHtcblxuICAgICAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAgICAgICAgICAgY29uc3Qgb2xkV2lkdGggPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TmV3VmlkZW9EaW1lbnNpb25zID0gKCk6IFByb21pc2U8eyBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciB9PiA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTGltaXRhdGlvbjogbXVzdCBnZXQgbmV3IGRpbWVuc2lvbnMgZnJvbSBhbiBleGlzdGluZyB2aWRlbyBlbGVtZW50IGFscmVhZHkgaW5zZXJ0ZWQgaW50byBET01cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9IZWlnaHRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgLy8gTmV3IHJlc29sdXRpb24gZ290IGZyb20gZGlmZmVyZW50IHBsYWNlcyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94LiBDaHJvbWUgbmVlZHMgYSB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBvZiBhIHZpZGVvRWxlbWVudC5cbiAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggbmVlZHMgZ2V0U2V0dGluZ3MgZnJvbSB0aGUgdmlkZW9UcmFja1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFNldHRpbmdzID0gcHVibGlzaGVyLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLndpZHRoIDogcHVibGlzaGVyLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gPG51bWJlcj4oKHBsYXRmb3JtLm5hbWUhIS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTEpID8gZmlyZWZveFNldHRpbmdzLmhlaWdodCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHsgbmV3V2lkdGgsIG5ld0hlaWdodCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcmVwZWF0VW50aWxDaGFuZ2UgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgIGdldE5ld1ZpZGVvRGltZW5zaW9ucygpLnRoZW4obmV3RGltZW5zaW9ucyA9PiB7XG4gICAgICAgICAgICAgICAgc2VuZFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMubmV3V2lkdGgsIG5ld0RpbWVuc2lvbnMubmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA3NSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCA9IChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICAgIGF0dGVtcHRzKys7XG4gICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDEwKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobmV3V2lkdGggIT09IG9sZFdpZHRoIHx8IG5ld0hlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnZGV2aWNlUm90YXRlZCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCAndmlkZW9EaW1lbnNpb25zJywgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LCAnZGV2aWNlUm90YXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICovXG4gIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gIH1cblxuXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICpcbiAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgKlxuICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2AgZXZlbnQgb25jZSB0aGUgbG9jYWwgc3RyZWFtcyBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIFtbUHVibGlzaGVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBpbml0UHVibGlzaGVyYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcGFyYW0yPywgcGFyYW0zPyk6IFB1Ymxpc2hlciB7XG5cbiAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykpIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0gKDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMik7XG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGF1ZGlvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZyYW1lUmF0ZTogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLmZyYW1lUmF0ZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5mcmFtZVJhdGUgOiB1bmRlZmluZWQpLFxuICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCcpID8gKCh0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJykgPyBWaWRlb0luc2VydE1vZGVbcHJvcGVydGllcy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6ICh0eXBlb2YgcHJvcGVydGllcy5taXJyb3IgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiAodHlwZW9mIHByb3BlcnRpZXMucHVibGlzaEF1ZGlvICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hWaWRlbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/IHVuZGVmaW5lZCA6ICgodHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5yZXNvbHV0aW9uIDogJzY0MHg0ODAnKSxcbiAgICAgICAgdmlkZW9Tb3VyY2U6ICh0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmlsdGVyOiBwcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgIG1pcnJvcjogdHJ1ZSxcbiAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgIHJlc29sdXRpb246ICc2NDB4NDgwJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gICAgaWYgKCEhcGFyYW0yICYmICh0eXBlb2YgcGFyYW0yID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgfSBlbHNlIGlmICghIXBhcmFtMykge1xuICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgfVxuXG4gICAgcHVibGlzaGVyLmluaXRpYWxpemUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoZXJzLnB1c2gocHVibGlzaGVyKTtcbiAgICByZXR1cm4gcHVibGlzaGVyO1xuICB9XG5cblxuICAvKipcbiAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKlxuICAgKiA+IFdBUk5JTkc6IGV2ZW50cyBgYWNjZXNzRGlhbG9nT3BlbmVkYCBhbmQgYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgd2lsbCBub3QgYmUgZGlzcGF0Y2hlZCBpZiB1c2luZyB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAqL1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgKi9cbiAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcbiAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgLy8gUmVqZWN0IGlQaG9uZXMgYW5kIGlQYWRzIGlmIG5vdCBTYWZhcmkgKCdTYWZhcmknIGFsc28gY292ZXJzIElvbmljIGZvciBpT1MpXG4gICAgaWYgKGZhbWlseSA9PT0gJ2lPUycgJiYgKGJyb3dzZXIgIT09ICdTYWZhcmknIHx8IHVzZXJBZ2VudC5pbmRleE9mKCdDcmlPUycpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZignRnhpT1MnKSAhPT0gLTEpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBBY2NlcHQ6IENocm9tZSAoZGVza3RvcCBhbmQgQW5kcm9pZCksIEZpcmVmb3ggKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBPcGVyYSAoZGVza3RvcCBhbmQgQW5kcm9pZCksXG4gICAgLy8gU2FmYXJpIChPU1ggYW5kIGlPUyksIElvbmljIChBbmRyb2lkIGFuZCBpT1MpXG4gICAgaWYgKFxuICAgICAgKGJyb3dzZXIgIT09ICdTYWZhcmknKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0Nocm9tZSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94IE1vYmlsZScpICYmXG4gICAgICAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYSBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdBbmRyb2lkIEJyb3dzZXInKSAmJiAoYnJvd3NlciAhPT0gJ0VsZWN0cm9uJylcbiAgICApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAqL1xuICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBicm93c2VyID0gcGxhdGZvcm0ubmFtZTtcbiAgICBjb25zdCBmYW1pbHkgPSBwbGF0Zm9ybS5vcyEhLmZhbWlseTtcblxuICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnIHx8IGZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoKGJyb3dzZXIgIT09ICdDaHJvbWUnKSAmJiAoYnJvd3NlciAhPT0gJ0ZpcmVmb3gnKSAmJiAoYnJvd3NlciAhPT0gJ09wZXJhJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEgW1tEZXZpY2VdXSBvYmplY3QgYXMgdmFsdWUgb2YgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAqL1xuICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZGV2aWNlSW5mb3MgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyBbW2luaXRQdWJsaXNoZXJdXSAocGFzcyBfTWVkaWFTdHJlYW1UcmFja18gcHJvcGVydHkgb2YgdGhlIF9NZWRpYVN0cmVhbV8gdmFsdWUgcmVzb2x2ZWQgYnkgdGhlIFByb21pc2UgYXMgYGF1ZGlvU291cmNlYCBvciBgdmlkZW9Tb3VyY2VgIHByb3BlcnRpZXMgaW4gW1tpbml0UHVibGlzaGVyXV0pXG4gICAqXG4gICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICpcbiAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAqIGBgYFxuICAgKiB2YXIgT1YgPSBuZXcgT3BlblZpZHUoKTtcbiAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICpcbiAgICogT1YuZ2V0VXNlck1lZGlhKHtcbiAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlO1xuICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgKiAgICByZXNvbHV0aW9uOiAnMTI4MHg3MjAnLFxuICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICogfSlcbiAgICogLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgKlxuICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgKlxuICAgKiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgKlxuICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgKiAgICAgICAgaWYgKCF2aWRlby5wYXVzZWQgJiYgIXZpZGVvLmVuZGVkKSB7XG4gICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICogICAgICAgIH1cbiAgICogICAgICB9O1xuICAgKiAgICAgIGxvb3AoKTtcbiAgICogICAgfSk7XG4gICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICpcbiAgICogICAgdmFyIGdyYXlWaWRlb1RyYWNrID0gY2FudmFzLmNhcHR1cmVTdHJlYW0oRlJBTUVfUkFURSkuZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAqICAgICAge1xuICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAqICAgICAgfSk7XG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMob3B0aW9ucylcbiAgICAgICAgLnRoZW4oY29uc3RyYWludHMgPT4ge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4obWVkaWFTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3I6IE9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgLyoqXG4gICAqIERpc2FibGUgYWxsIGxvZ2dpbmcgZXhjZXB0IGVycm9yIGxldmVsXG4gICAqL1xuICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmRlYnVnID0gKCkgPT4geyB9O1xuICAgIGNvbnNvbGUuaW5mbyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLndhcm4gPSAoKSA9PiB7IH07XG4gIH1cbiAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG5cbiAgLyoqXG4gICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEN1cnJlbnRseSBgY29uZmlndXJhdGlvbmAgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzIChzZWUgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbl1dIGZvciBtb3JlIGRldGFpbHMpOlxuICAgKiAtIGBpY2VTZXJ2ZXJzYDogc2V0IGN1c3RvbSBTVFVOL1RVUk4gc2VydmVycyB0byBiZSB1c2VkIGJ5IE9wZW5WaWR1IEJyb3dzZXJcbiAgICogLSBgc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25gOiB1cmwgdG8gYSBjdXN0b20gc2NyZWVuIHNoYXJlIGV4dGVuc2lvbiBmb3IgQ2hyb21lIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmUsIGJhc2VkIG9uIG91cnMgW2h0dHBzOi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdS1zY3JlZW4tc2hhcmluZy1jaHJvbWUtZXh0ZW5zaW9uXShodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbilcbiAgICogLSBgcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zYDogY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlXG4gICAqL1xuICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gIH1cblxuXG4gIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBhdWRpbywgdmlkZW87XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGF1ZGlvID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdWRpbyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdWRpbyA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBudWxsIHx8IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZpZGVvID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWRlbyA9IHtcbiAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICBpZGVhbDogNjQwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZWRpYUNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbyxcbiAgICAgICAgdmlkZW9cbiAgICAgIH07XG5cbiAgICAgIGlmICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFDb25zdHJhaW50cy5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IG1lZGlhQ29uc3RyYWludHMuYXVkaW8gfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobWVkaWFDb25zdHJhaW50cy52aWRlbykge1xuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbikge1xuICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLndpZHRoLmlkZWFsID0gd2lkdGg7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS5oZWlnaHQuaWRlYWwgPSBoZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSkge1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuZnJhbWVSYXRlID0geyBpZGVhbDogcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgJiYgdHlwZW9mIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicgJiYgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpKSB7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCwgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggb3IgT3BlcmEuIERldGVjdGVkIGJyb3dzZXI6ICcgKyBwbGF0Zm9ybS5uYW1lKTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IFwic2NyZWVuOlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcubGFzdEluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uRGVzdHJveWVkJywgY29ubmVjdGlvbiwgbXNnLnJlYXNvbildKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkW2Nvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkXSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdID0gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24ocmVzcG9uc2UuaWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgcmVzcG9uc2UuaWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50UHVibGlzaGVkJy4gXCIgK1xuICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgLnRoZW4oY29uID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKHJlc3BvbnNlLnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuc3RvcFB1Ymxpc2hlclN0cmVhbShtc2cucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCBcIlJlbW90ZSBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgdW5rbm93biB3aGVuICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSlcblxuICAgICAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpc1NlbmRlckFuZEN1c3RvbVRyYWNrOiBib29sZWFuID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9wV2ViUnRjU3RhdHMoKTtcblxuICAgICAgICBjb25zb2xlLmluZm8oKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICsgXCJXZWJSVENQZWVyIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGNsb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlTWVkaWFTdHJlYW0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdFbGVjdHJvbicpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9IHR5cGVvZiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmIHNjcmVlbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgaGFya09wdGlvbnMuaW50ZXJ2YWwgPSAodHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDUwO1xuICAgICAgICAgICAgaGFya09wdGlvbnMudGhyZXNob2xkID0gKHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIFtuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3NwZWFraW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbigndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgaGFya0V2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5zcGVha2luZ0V2ZW50c0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyAncHVibGlzaGVyU3RhcnRTcGVha2luZycgYW5kL29yIHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgZXZlbnRzIGFyZSBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbCgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gaW5ib3VuZCBvcHRpb25zIHVuZGVmaW5lZCBhbmQgb3V0Ym91bmQgb3B0aW9ucyBkZWZpbmVkXG4gICAgICAgIHJldHVybiAoIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVwb3J0ID0+IHJlc29sdmUocmVwb3J0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyU2VuZCgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCB1c2VyTWVkaWFDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWVkaWFTdHJlYW06IHRoaXMubWVkaWFTdHJlYW0sXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdXNlck1lZGlhQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbyA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPSAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSA/ICdDVVNUT00nIDogKHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3B1Ymxpc2hWaWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5wcm9jZXNzQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlciwgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCB0byBzZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhvZmZlcik7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogb2ZmZXJDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBpY2VTZXJ2ZXJzOiB0aGlzLmdldEljZVNlcnZlcnNDb25mKCksXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBzdWJzY3JpYmUgdG8gJ1xuICAgICAgICAgICAgICAgICAgICArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVjZWl2ZVZpZGVvRnJvbScsIHtcbiAgICAgICAgICAgICAgICAgICAgc2VuZGVyOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJb3MgSW9uaWMuIExpbWl0YXRpb246IHNvbWUgYnVnIGluIGlvc3J0YyBjb3Jkb3ZhIHBsdWdpbiBtYWtlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVjZXNzYXJ5IHRvIGFkZCBhIHRpbWVvdXQgYmVmb3JlIHByb2Nlc3NBbnN3ZXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvblsnaW9zSW50ZXJ2YWwnXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVycyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZ2VuZXJhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy53ZWJSdGNQZWVyLnBjO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHBjMS5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZygnUGVlciByZW1vdGUgc3RyZWFtJywgdGhpcy5tZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9ICEhKCg8U3Vic2NyaWJlcj50aGlzLnN0cmVhbU1hbmFnZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSAmJiAhIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAmJiB0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVTcGVha2luZ0V2ZW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnID9cbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0U2VuZGVycygpLmZvckVhY2goc2VuZGVyID0+IHNlbmRlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuZ2V0UmVjZWl2ZXJzKCkuZm9yRWFjaChyZWNlaXZlciA9PiByZWNlaXZlci5nZXRTdGF0cygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2gocmVwb3J0ID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gKHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSkgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICByZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICogWW91IGNhbiBpbnNlcnQgYXMgbWFueSB2aWRlbyBwbGF5ZXJzIGZvIHRoZSBzYW1lIFN0cmVhbSBhcyB5b3Ugd2FudCBieSBjYWxsaW5nIFtbU3RyZWFtTWFuYWdlci5hZGRWaWRlb0VsZW1lbnRdXSBvclxuICogW1tTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudF1dLlxuICpcbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmlyc3RWaWRlb0VsZW1lbnQ6IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG5cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiWW91ciBsb2NhbCAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgb3duIHJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICdyZW1vdGVWaWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiUmVtb3RlICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXSB2aWRlbyBpcyBub3cgcGxheWluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbih0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2VcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnIHx8IHR5cGUgPT09ICd2aWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb1BsYXlpbmcnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnICYmIHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFN0cmVhbU1hbmFnZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKVxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIGEgdmlkZW8gYWxyZWFkeSBhZGRlZCB0byBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGNhdXNlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGJlXG4gICAgICogZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgcHJldmlvdXMgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIHRvIGJlIGFzc29jaWF0ZWQgdG8gdGhpcyBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSB2aWRlbyB3YXNuJ3QgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKiAwIGlmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiAtMSBpZiB0aGUgdmlkZW8gd2FzIHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0byBhbnkgb3RoZXJcbiAgICAgKiBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IG9uZSBhbmQgcHJvcGVybHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICovXG4gICAgYWRkVmlkZW9FbGVtZW50KHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogbnVtYmVyIHtcblxuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goc3RyZWFtTWFuYWdlciA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHtcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScpIHtcbiAgICAgICAgICAgIHZpZGVvLnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFx0XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMucmVtb3RlICYmICF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKScgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgb25jYW5wbGF5IGV2ZW50IGxpc3RlbmVyIChvbmx5IE9wZW5WaWR1IGJyb3dzZXIgbGlzdGVuZXIsIG5vdCB0aGUgdXNlciBvbmVzKVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQoc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50RGVzdHJveWVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSBzcmNPYmplY3QgZnJvbSB0aGUgdmlkZW9cbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIodiA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1ZpZGVvIGVsZW1lbnQgZGlzYXNzb2NpYXRlZCBmcm9tICcsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaXNhc3NvY2lhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRQbGF5RXZlbnRUb0ZpcnN0VmlkZW8oKSB7XG4gICAgICAgIGlmICgoISF0aGlzLnZpZGVvc1swXSkgJiYgKCEhdGhpcy52aWRlb3NbMF0udmlkZW8pICYmICghdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKHN0cmVhbU1hbmFnZXJWaWRlbyA9PiB7XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG4gICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcblxuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgYXVkaW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1ZpZGVvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIERlZmluZXMgcHJvcGVydHkgW1tPcGVuVmlkdUVycm9yLm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBPcGVuVmlkdUVycm9yTmFtZSB7XG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBBY2N1cmFjeSBvZiB0aGlzIHByb3BlcnR5IGlzIG9ubHkgZ3JhbnRlZCBmb3IgQ2hyb21lIGFuZCBGaXJlZm94IGNsaWVudHMuIFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSBcIkRFVklDRV9BTFJFQURZX0lOX1VTRVwiLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gY2FwdHVyZSBzb21lIGRlc2t0b3Agc2NyZWVuIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCA9ICdPUEVOVklEVV9OT1RfQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIF9Ob3QgaW4gdXNlIHlldF9cbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogSG93IHRoZSB2aWRlbyB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBET00gZm9yIFB1Ymxpc2hlcnMgYW5kIFN1YnNjcmliZXJzLiBTZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSBhbmQgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV1cbiAqL1xuZXhwb3J0IGVudW0gVmlkZW9JbnNlcnRNb2RlIHtcblxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBjb25uZWN0aW9uQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYGNvbm5lY3Rpb25EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBldmVudCBoYXMgYSBkZWZhdWx0IGJlaGF2aW9yIHRoYXQgbWF5IGJlIHByZXZlbnRlZCBieSBjYWxsaW5nIFtbRXZlbnQucHJldmVudERlZmF1bHRdXVxuICAgICAqL1xuICAgIGNhbmNlbGFibGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgZXZlbnQuIFRoaXMgaXMgdGhlIHNhbWUgc3RyaW5nIHlvdSBwYXNzIGFzIGZpcnN0IHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgbWV0aG9kIGBvbigpYCBvZiBhbnkgb2JqZWN0IGltcGxlbWVudGluZyBbW0V2ZW50RGlzcGF0Y2hlcl1dIGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIFtbRXZlbnQucHJldmVudERlZmF1bHRdXSB0byBwcmV2ZW50IGl0XG4gICAgICovXG4gICAgaXNEZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNCZWVuUHJldmVudGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBldmVudC4gVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSBhIGRlZmF1bHQgYmVoYXZpb3I6XG4gICAgICpcbiAgICAgKiAtIGBzZXNzaW9uRGlzY29ubmVjdGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBvYmplY3QsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHsgfTtcbiAgICAgICAgdGhpcy5oYXNCZWVuUHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyBbW0ZpbHRlci5hZGRFdmVudExpc3RlbmVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgcHVibGlzaGVyU3RvcFNwZWFraW5nYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb246XG4gKiAtIFRoaXMgZXZlbnRzIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgZm9yICoqcmVtb3RlIHN0cmVhbXMgdGhhdCBoYXZlIGF1ZGlvIHRyYWNrcyoqIChbW1N0cmVhbS5oYXNBdWRpb11dIG11c3QgYmUgdHJ1ZSlcbiAqIC0gQm90aCBldmVudHMgc2hhcmUgdGhlIHNhbWUgbGlmZWN5Y2xlLiBUaGF0IG1lYW5zIHRoYXQgeW91IGNhbiBzdWJzY3JpYmUgdG8gb25seSBvbmUgb2YgdGhlbSBpZiB5b3Ugd2FudCwgYnV0IGlmIHlvdSBjYWxsIGBTZXNzaW9uLm9mZigncHVibGlzaGVyU3RvcFNwZWFraW5nJylgLFxuICoga2VlcCBpbiBtaW5kIHRoYXQgdGhpcyB3aWxsIGFsc28gaW50ZXJuYWxseSByZW1vdmUgYW55ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyBldmVudFxuICogLSBZb3UgY2FuIGZ1cnRoZXIgY29uZmlndXJlIGhvdyB0aGUgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IHNldHRpbmcgcHJvcGVydHkgYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2AgaW4gdGhlIGNhbGwgb2YgW1tPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyU3BlYWtpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcmVjb3JkaW5nU3RhcnRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHJlY29yZGluZ1N0b3BwZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oaHR0cHM6Ly9vcGVudmlkdS5pby9kb2NzL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jYXV0b21hdGljLXN0b3Atb2YtcmVjb3JkaW5ncylcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHN0b3BwZWQgKG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG1lZGlhIHNlcnZlcilcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5zdHJlYW1JZF07XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF07XG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc2lnbmFsYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICogLSBgc2lnbmFsOlRZUEVgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbCAoY2FuIGJlIGVtcHR5KS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHJlY2VpdmUgdGhpcyBvYmplY3QgaW4gdGhlIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgdHlwZXMgb2Ygc2lnbmFscy5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW10cHkpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGZyb206IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZnJvbTogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtQ3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqIC0gYHN0cmVhbURlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYW5kIFtbUHVibGlzaGVyXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJtZWRpYVNlcnZlckRpc2Nvbm5lY3RcIjogT3BlblZpZHUgTWVkaWEgU2VydmVyIGhhcyBjcmFzaGVkIG9yIGxvc3QgaXRzIGNvbm5lY3Rpb24uIEEgbmV3IG1lZGlhIHNlcnZlciBpbnN0YW5jZSBpcyBhY3RpdmUgYW5kIG5vIG1lZGlhIHN0cmVhbXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgbWVkaWEgc2VydmVyXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZFt0aGlzLnN0cmVhbS5zdHJlYW1JZF07XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW3RoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24gJiYgISFyZW1vdGVDb25uZWN0aW9uLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zU2VydmVyID0gcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zLnN0cmVhbXM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0cmVhbU9wdGlvbnNTZXJ2ZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbU9wdGlvbnNTZXJ2ZXJbaV0uaWQgPT09IHRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1PcHRpb25zU2VydmVyLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGBzdHJlYW1QbGF5aW5nYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW5ldmVyIGl0cyBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcgKG9uZSBvZiBpdHMgdmlkZW9zIGhhcyBtZWRpYVxuICogYW5kIGhhcyBiZWd1biB0byBwbGF5KS4gVGhpcyBldmVudCB3aWxsIGJlIGRpc3BhdGNoZWQgd2hlbiB0aGVzZSAzIGNvbmRpdGlvbnMgYXJlIG1ldCAxKSBUaGUgU3RyZWFtTWFuYWdlciBoYXMgbm8gdmlkZW8gYXNzb2NpYXRlZCBpbiB0aGUgRE9NIDIpIEl0IGlzIGFzc29jaWF0ZWQgdG8gb25lIHZpZGVvIDMpIFRoYXQgdmlkZW8gc3RhcnRzIHBsYXlpbmdcbiAqIC0gYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYDogZGlzcGF0Y2hlZCBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pIHdoZW4gdGhlIHZvbHVtZSBvZiBpdHMgU3RyZWFtJ3MgYXVkaW8gdHJhY2tcbiAqIGNoYW5nZXMuIE9ubHkgYXBwbGllcyBpZiBbW1N0cmVhbS5oYXNBdWRpb11dIGlzIGB0cnVlYC4gVGhlIGZyZXF1ZW5jeSB0aGlzIGV2ZW50IGlzIGZpcmVkIHdpdGggaXMgZGVmaW5lZCBieSBwcm9wZXJ0eSBgaW50ZXJ2YWxgIG9mXG4gKiBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc11dIChkZWZhdWx0IDUwbXMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1NYW5hZ2VyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqIFxuICAgICAqIEZvciBgc3RyZWFtUGxheWluZ2AgZXZlbnQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgdmFsdWU6IE9iamVjdCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlbnQgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSBhcyB3ZWxsIGFzIGJ5IFtbU3RyZWFtTWFuYWdlcl1dIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSkuXG4gKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW55IHJlbW90ZSBzdHJlYW0gKG93bmVkIGJ5IGEgU3Vic2NyaWJlcikgb3IgbG9jYWwgc3RyZWFtIChvd25lZCBieSBhIFB1Ymxpc2hlcikgdW5kZXJnb2VzXG4gKiBhbnkgY2hhbmdlIGluIGFueSBvZiBpdHMgbXV0YWJsZSBwcm9wZXJ0aWVzIChzZWUgW1tjaGFuZ2VkUHJvcGVydHldXSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ2F1c2Ugb2YgdGhlIGNoYW5nZSBvbiB0aGUgc3RyZWFtJ3MgcHJvcGVydHk6XG4gICAgICogLSBGb3IgYHZpZGVvQWN0aXZlYDogYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogLSBGb3IgYGF1ZGlvQWN0aXZlYDogYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogLSBGb3IgYHZpZGVvRGltZW5zaW9uc2A6IGBcImRldmljZVJvdGF0ZWRcImAgb3IgYFwic2NyZWVuUmVzaXplZFwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYWZ0ZXIgY2hhbmdlLCBjdXJyZW50IHZhbHVlKVxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGJlZm9yZSBjaGFuZ2UpXG4gICAgICovXG4gICAgb2xkVmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCBzdHJlYW06IFN0cmVhbSwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QsIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuXG4vKipcbiAqIERlZmluZXMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAtIGB2aWRlb0VsZW1lbnRDcmVhdGVkYDogZGlzcGF0Y2hlZCBieSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSB3aGVuZXZlciBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LiBTZWVcbiAqIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcykgc2VjdGlvbi5cbiAqIC0gYHZpZGVvRWxlbWVudERlc3Ryb3llZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYW4gSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBET00gYnkgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgVmlkZW9FbGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiZnVuY3Rpb24gTWFwcGVyKClcbntcbiAgdmFyIHNvdXJjZXMgPSB7fTtcblxuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKVxuICB7XG4gICAgZm9yKHZhciBrZXkgaW4gc291cmNlcylcbiAgICB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICBmb3IodmFyIGtleTIgaW4gc291cmNlKVxuICAgICAgICBjYWxsYmFjayhzb3VyY2Vba2V5Ml0pO1xuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbihpZCwgc291cmNlKVxuICB7XG4gICAgdmFyIGlkcyA9IHNvdXJjZXNbc291cmNlXTtcbiAgICBpZihpZHMgPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBpZHNbaWRdO1xuICB9O1xuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybjtcblxuICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgIGZvcih2YXIgaSBpbiBpZHMpe3JldHVybiBmYWxzZX1cblxuICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gIH07XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbih2YWx1ZSwgaWQsIHNvdXJjZSlcbiAge1xuICAgIGlmKHZhbHVlID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHNvdXJjZXNbc291cmNlXSA9IGlkcyA9IHt9O1xuXG4gICAgaWRzW2lkXSA9IHZhbHVlO1xuICB9O1xufTtcblxuXG5NYXBwZXIucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG57XG4gIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ICA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCAgPSBKc29uUnBjQ2xpZW50OyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgUnBjQnVpbGRlciA9IHJlcXVpcmUoJy4uLycpO1xudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5EYXRlLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsIFwicHVzaFwiKTtcbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgc3RhdHVzID0gUkVDT05ORUNUSU5HO1xuICAgICAgICBpZiAob25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuXG4gICAgICAgIGlmIChvbnJlY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OQ09OTkVDVEVEIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXNlUGluZygpO1xuXG4gICAgICAgIGlmIChvbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24od3NDb25maWcpO1xuXG4gICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW5nIHdlYnNvY2tldCB0byBVUkk6ICcgKyB3c0NvbmZpZy51cmkpO1xuXG4gICAgdmFyIHJwY0J1aWxkZXJPcHRpb25zID0ge1xuICAgICAgICByZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLnJlcXVlc3RUaW1lb3V0LFxuICAgICAgICBwaW5nX3JlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMuaGVhcnRiZWF0UmVxdWVzdFRpbWVvdXRcbiAgICB9O1xuXG4gICAgdmFyIHJwYyA9IG5ldyBScGNCdWlsZGVyKFJwY0J1aWxkZXIucGFja2Vycy5Kc29uUlBDLCBycGNCdWlsZGVyT3B0aW9ucywgd3MsXG4gICAgICAgIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BpbmcnKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlcXVlc3Q6IG1ldGhvZDonICsgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJwYy5lbmNvZGUobWV0aG9kLCBwYXJhbXMsIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUjpcIiArIGVycm9yLm1lc3NhZ2UgKyBcIiBpbiBSZXF1ZXN0OiBtZXRob2Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kICsgXCIgcGFyYW1zOlwiICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArIFwiIHJlcXVlc3Q6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFUlJPUiBEQVRBOlwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwibm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IFwiICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArXG4gICAgICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuICsgJyknKTtcbiAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IHBpbmdOZXh0TnVtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlbmRQaW5nKCkge1xuICAgICAgICBpZiAoZW5hYmxlZFBpbmdzKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChwaW5nTmV4dE51bSA9PSAwIHx8IHBpbmdOZXh0TnVtID09IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCB8fCBQSU5HX0lOVEVSVkFMXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBpbmdOZXh0TnVtKys7XG5cbiAgICAgICAgICAgIHNlbGYuc2VuZCgncGluZycsIHBhcmFtcywgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiRXJyb3IgaW4gcGluZyByZXF1ZXN0ICNcIiArIHBpbmdOdW0gKyBcIiAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGluZ051bSA+IG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgI1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluZ051bSArIFwiLiBSZWNvbm5lY3RpbmcuLi4gXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KShwaW5nTmV4dE51bSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVHJ5aW5nIHRvIHNlbmQgcGluZywgYnV0IHBpbmcgaXMgbm90IGVuYWJsZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlN0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpXCIpXG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2luZyAgd2l0aCBjb2RlOiBcIiArIGNvZGUgKyBcIiBiZWNhdXNlOiBcIiArIHJlYXNvbik7XG5cbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsZWFyaW5nIHBpbmcgaW50ZXJ2YWxcIik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjb25maWd1cmF0aW9uLnNlbmRDbG9zZU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlbmRpbmcgY2xvc2UgbWVzc2FnZVwiKVxuICAgICAgICAgICAgdGhpcy5zZW5kKCdjbG9zZVNlc3Npb24nLCBudWxsLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nIGNsb3NlIG1lc3NhZ2U6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAwO1xuICAgICAgICB1c2VQaW5nKCk7XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcblx0fTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuXG4gICAgdmFyIGNsb3NpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB2YXIgd3NVcmkgPSBjb25maWcudXJpO1xuICAgIHZhciB1c2VTb2NrSlMgPSBjb25maWcudXNlU29ja0pTO1xuICAgIHZhciByZWNvbm5lY3RpbmcgPSBmYWxzZTtcblxuICAgIHZhciBmb3JjaW5nRGlzY29ubmVjdGlvbiA9IGZhbHNlO1xuXG4gICAgdmFyIHdzO1xuXG4gICAgaWYgKHVzZVNvY2tKUykge1xuICAgICAgICB3cyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG4gICAgfVxuXG4gICAgd3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgY29uZmlnLm9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVjbHkuIFJlY29ubmVjdGluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0XCIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0VG9TYW1lVXJpIChhdHRlbXB0ICNcIiArIG51bVJldHJpZXMgKyBcIiwgbWF4PVwiICsgbWF4UmV0cmllcyArIFwiKVwiKTtcblxuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKFwiVHJ5aW5nIHRvIHJlY29ubmVjdFRvTmV3VXJpIHdoZW4gcmVjb25uZWN0aW5nLi4uIElnbm9yaW5nIHRoaXMgcmVjb25uZWN0aW9uLlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvcmNpbmdEaXNjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKGZ1bmN0aW9uIChlcnJvciwgbmV3V3NVcmkpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiUmVjb25uZWN0ZWQgYWZ0ZXIgXCIgKyBudW1SZXRyaWVzICsgXCIgYXR0ZW1wdHMuLi5cIik7XG4gICAgICAgICAgICBsb2dDb25uZWN0ZWQobmV3V3MsIHdzVXJpKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuZXdXcy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb25FcnJvck9yQ2xvc2UgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKFwiUmVjb25uZWN0aW9uIGVycm9yOiBcIiwgZXJyb3IpO1xuXG4gICAgICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcub25kaXNjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsb3NpbmcgPSB0cnVlO1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cblxuICAgIC8vIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmdcbiAgICB0aGlzLmZvcmNlQ2xvc2UgPSBmdW5jdGlvbiAobWlsbGlzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRlc3Rpbmc6IEZvcmNlIFdlYlNvY2tldCBjbG9zZVwiKTtcblxuICAgICAgICBpZiAobWlsbGlzKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBDaGFuZ2Ugd3NVcmkgZm9yIFwiICsgbWlsbGlzICsgXCIgbWlsbGlzIHRvIHNpbXVsYXRlIG5ldCBmYWlsdXJlXCIpO1xuICAgICAgICAgICAgdmFyIGdvb2RXc1VyaSA9IHdzVXJpO1xuICAgICAgICAgICAgd3NVcmkgPSBcIndzczovLzIxLjIzNC4xMi4zNC40OjQ0My9cIjtcblxuICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSB0cnVlO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFdzXCIpO1xuICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cblxudmFyIGRlZmluZVByb3BlcnR5X0lFOCA9IGZhbHNlXG5pZihPYmplY3QuZGVmaW5lUHJvcGVydHkpXG57XG4gIHRyeVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCBcInhcIiwge30pO1xuICB9XG4gIGNhdGNoKGUpXG4gIHtcbiAgICBkZWZpbmVQcm9wZXJ0eV9JRTggPSB0cnVlXG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRnVuY3Rpb24vYmluZFxuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKG9UaGlzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgfVxuXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgZk5PUCAgICA9IGZ1bmN0aW9uKCkge30sXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpc1xuICAgICAgICAgICAgICAgICA/IHRoaXNcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcbiAgICAgICAgICAgICAgICAgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgfTtcblxuICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICByZXR1cm4gZkJvdW5kO1xuICB9O1xufVxuXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwYWNrZXJzID0gcmVxdWlyZSgnLi9wYWNrZXJzJyk7XG52YXIgTWFwcGVyID0gcmVxdWlyZSgnLi9NYXBwZXInKTtcblxuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpXG57XG4gIGlmKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICBmb3IodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpXG4gIHtcbiAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID1cbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHJlc3BvbnNlTWV0aG9kcztcbn07XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydClcbntcbiAgaWYoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gIC8vIFRyYW5zcG9ydCBhcyBhIGZ1bmN0aW9uXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB7c2VuZDogdHJhbnNwb3J0fTtcblxuICAvLyBXZWJTb2NrZXQgJiBEYXRhQ2hhbm5lbFxuICBpZih0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgLy8gTWVzc2FnZSBBUEkgKEludGVyLXdpbmRvdyAmIFdlYldvcmtlcilcbiAgaWYodHJhbnNwb3J0LnBvc3RNZXNzYWdlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gU3RyZWFtIEFQSVxuICBpZih0cmFuc3BvcnQud3JpdGUgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBUcmFuc3BvcnRzIHRoYXQgb25seSBjYW4gcmVjZWl2ZSBtZXNzYWdlcywgYnV0IG5vdCBzZW5kXG4gIGlmKHRyYW5zcG9ydC5vbm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZih0cmFuc3BvcnQucGF1c2UgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuO1xuXG4gIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3RcIik7XG59O1xuXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgbm90aWZpY2F0aW9uXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAqL1xuZnVuY3Rpb24gUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKVxue1xuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZFxuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gIH1cbiAgZWxzZVxuICB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXRob2QnLCB7dmFsdWU6IG1ldGhvZCwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge3ZhbHVlOiBwYXJhbXMsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KVxue1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYoIXBhY2tlcilcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gIGlmKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaylcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG5cbiAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgaWYob25SZXF1ZXN0ICYmICEob25SZXF1ZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblxuICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICBpZihvblJlcXVlc3QpXG4gICAgdGhpcy5vbigncmVxdWVzdCcsIG9uUmVxdWVzdCk7XG5cblxuICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRFxuICBlbHNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwZWVySUQnLCB7dmFsdWU6IG9wdGlvbnMucGVlcklEfSk7XG5cbiAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG5cbiAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudClcbiAge1xuICAgIHNlbGYuZGVjb2RlKGV2ZW50LmRhdGEgfHwgZXZlbnQpO1xuICB9O1xuXG4gIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICB7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICB7XG4gICAgLy8gUmVtb3ZlIGxpc3RlbmVyIGZyb20gb2xkIHRyYW5zcG9ydFxuICAgIGlmKHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICBpZih2YWx1ZSlcbiAgICB7XG4gICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgaWYodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHZhbHVlLmFkZExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gIH1cblxuICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICB7XG4gICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICB9KVxuXG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cblxuICB2YXIgcmVxdWVzdF90aW1lb3V0ICAgICAgPSBvcHRpb25zLnJlcXVlc3RfdGltZW91dCAgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIHBpbmdfcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5waW5nX3JlcXVlc3RfdGltZW91dCB8fCByZXF1ZXN0X3RpbWVvdXQ7XG4gIHZhciByZXNwb25zZV90aW1lb3V0ICAgICA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgZHVwbGljYXRlc190aW1lb3V0ICAgPSBvcHRpb25zLmR1cGxpY2F0ZXNfdGltZW91dCAgIHx8IEJBU0VfVElNRU9VVDtcblxuXG4gIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gIHZhciByZXF1ZXN0cyAgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gIHZhciBwcm9jZXNzZWRSZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG5cbiAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdClcbiAge1xuICAgIHZhciByZXNwb25zZSA9XG4gICAge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlcy5yZW1vdmUoaWQsIGRlc3QpO1xuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgfTtcblxuICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIGlnbm9yZSBkdXBsaWNhdGVkIG1lc3NhZ2VzIGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSlcbiAge1xuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpXG4gICAge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgIH0sXG4gICAgZHVwbGljYXRlc190aW1lb3V0KTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAqXG4gICAqIEBjbGFzc1xuICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICogQHBhcmFtIFtmcm9tXSAtIHNvdXJjZSBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KVxuICB7XG4gICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gICAge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG4gICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAgICB7XG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgIH0pXG5cbiAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgIC8qKlxuICAgICAqIEBjb25zdGFudCB7Qm9vbGVhbn0gZHVwbGljYXRlZFxuICAgICAqL1xuICAgIGlmKCEodHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCkpKVxuICAgIHtcbiAgICAgIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSlcbiAgICAgIGVsc2VcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJyxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZClcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYocmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgZWxzZSBpZihyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgfHwgcmVzdWx0ICYmIHJlc3VsdC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSByZXN1bHQ7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgaWYoZnJvbSAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgIGVycm9yLmRlc3QgPSBmcm9tO1xuXG4gICAgICAgIGlmKHJlc3VsdClcbiAgICAgICAgICByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICB9O1xuXG4gICAgICB2YXIgbWVzc2FnZTtcblxuICAgICAgLy8gTmV3IHJlcXVlc3Qgb3Igb3ZlcnJpZGVuIG9uZSwgY3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHByb3ZpZGVkIGRhdGFcbiAgICAgIGlmKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICB7XG4gICAgICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKGVycm9yKVxuICAgICAgICAgICAgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgaWYocmVzcG9uc2VNZXRob2QpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA/IHJlc3BvbnNlTWV0aG9kLmVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICB7XG4gICAgICAgICAgICBlcnJvcjogIGVycm9yLFxuICAgICAgICAgICAgcmVzdWx0OiByZXN1bHRcbiAgICAgICAgICB9O1xuXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIER1cGxpY2F0ZSAmIG5vdC1vdmVycmlkZW4gcmVxdWVzdCwgcmUtc2VuZCBvbGQgcmVzcG9uc2VcbiAgICAgIGVsc2UgaWYocmVzcG9uc2UpXG4gICAgICAgIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKHtyZXN1bHQ6IG51bGx9LCBpZCk7XG5cbiAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICBpZih0cmFuc3BvcnQpXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuICB9O1xuICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG5cbiAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpXG4gIHtcbiAgICB2YXIga2V5ID0gbWVzc2FnZTJLZXlbbWVzc2FnZV07XG4gICAgaWYoIWtleSkgcmV0dXJuO1xuXG4gICAgZGVsZXRlIG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuXG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgaWYoIXJlcXVlc3QpIHJldHVybjtcblxuICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2Uoa2V5LmlkLCBrZXkuZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICpcbiAgICogSWYgYG1lc3NhZ2VgIGlzIG5vdCBnaXZlbiwgY2FuY2VsIGFsbCB0aGUgcmVxdWVzdFxuICAgKi9cbiAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbihtZXNzYWdlKVxuICB7XG4gICAgaWYobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgIGZvcih2YXIgbWVzc2FnZSBpbiBtZXNzYWdlMktleSlcbiAgICAgIGNhbmNlbChtZXNzYWdlKTtcbiAgfTtcblxuXG4gIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpXG4gIHtcbiAgICAvLyBQcmV2ZW50IHRvIHJlY2VpdmUgbmV3IG1lc3NhZ2VzXG4gICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgaWYodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5jbG9zZSlcbiAgICAgIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCBcIkNhbmNlbCByZXF1ZXN0XCIpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvLyBMYXN0IHRpbWUgdXBkYXRlZCBvbiBKdW5lIDA4LCAyMDE4XG5cbi8vIExhdGVzdCBmaWxlIGNhbiBiZSBmb3VuZCBoZXJlOiBodHRwczovL2Nkbi53ZWJydGMtZXhwZXJpbWVudC5jb20vZ2V0U2NyZWVuSWQuanNcblxuLy8gTXVheiBLaGFuICAgICAgICAgLSB3d3cuTXVhektoYW4uY29tXG4vLyBNSVQgTGljZW5zZSAgICAgICAtIHd3dy5XZWJSVEMtRXhwZXJpbWVudC5jb20vbGljZW5jZVxuLy8gRG9jdW1lbnRhdGlvbiAgICAgLSBodHRwczovL2dpdGh1Yi5jb20vbXVhei1raGFuL2dldFNjcmVlbklkLlxuXG4vLyBfX19fX19fX19fX19fX1xuLy8gZ2V0U2NyZWVuSWQuanNcblxuLypcbmdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgIC8vIGVycm9yICAgID09IG51bGwgfHwgJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCAnbm90LWluc3RhbGxlZCcgfHwgJ2luc3RhbGxlZC1kaXNhYmxlZCcgfHwgJ25vdC1jaHJvbWUnXG4gICAgLy8gc291cmNlSWQgPT0gbnVsbCB8fCAnc3RyaW5nJyB8fCAnZmlyZWZveCdcbiAgICBcbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG53aW5kb3cuZ2V0U2NyZWVuSWQgPSBmdW5jdGlvbiAoZmlyZWZveFN0cmluZywgY2FsbGJhY2ssIGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdFZGdlJykgIT09IC0xICYmICghIW5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iIHx8ICEhbmF2aWdhdG9yLm1zU2F2ZUJsb2IpKSB7XG4gICAgICAgIC8vIG1pY3Jvc29mdCBlZGdlID0+IG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICAvLyBzb3VyY2VJZCA9PSAnZmlyZWZveCdcbiAgICAvLyBzY3JlZW5fY29uc3RyYWludHMgPSB7Li4ufVxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpcmVmb3gnLCB7XG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIG1vek1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nLFxuICAgICAgICAgICAgICAgIG1lZGlhU291cmNlOiBmaXJlZm94U3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMsIG51bGwsIGdldFNjcmVlbkNvbnN0cmFpbnRzKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogd2luZG93LnNjcmVlbi53aWR0aCA+IDE5MjAgPyB3aW5kb3cuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbmFsOiBbXVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICghIWNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyA9IHtcbiAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBlcnJvciA/ICdzY3JlZW4nIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEhY3VzdG9tX3BhcmFtZXRlci5mb3JFYWNoKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVDdXN0b21Tb3VyY2VJZDogY3VzdG9tX3BhcmFtZXRlclxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgIH0sICcqJyk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG53aW5kb3cuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxud2luZG93LmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIGlmICghIW5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgIH0sICcqJyk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnZXRTY3JlZW5JZDsiLCIvLyBnbG9iYWwgdmFyaWFibGVzXG52YXIgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbnZhciBzb3VyY2VJZDtcbnZhciBzY3JlZW5DYWxsYmFjaztcbnZhciBpc0ZpcmVmb3ggPSB0eXBlb2Ygd2luZG93Lkluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJztcbnZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG52YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG59KTtcblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIG5vdGlmaWVkIGhpcyBwcmVzZW5jZVxuICAgIGlmIChkYXRhID09ICdydGNtdWx0aWNvbm5lY3Rpb24tZXh0ZW5zaW9uLWxvYWRlZCcpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnZGVza3RvcCc7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBzaGFyZWQgdGVtcCBzb3VyY2VJZFxuICAgIGlmIChkYXRhLnNvdXJjZUlkICYmIHNjcmVlbkNhbGxiYWNrKSB7XG4gICAgICAgIHNjcmVlbkNhbGxiYWNrKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICB9LCAnKicpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICB9LCAyMDAwKTtcbiAgICB9O1xuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrKCdub3QtaW5zdGFsbGVkJyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgdHJ1ZSk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gZXhwbGFpbnMgaG93IHRvIHVzZSBhYm92ZSBtZXRob2RzL29iamVjdHNcbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICBzb3VyY2VJZCA9ICcnO1xuICAgIHZhciBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMgPSB7XG4gICAgICAgIG1vek1lZGlhU291cmNlOiAnd2luZG93JyxcbiAgICAgICAgbWVkaWFTb3VyY2U6ICd3aW5kb3cnXG4gICAgfTtcbiAgICBpZiAoaXNGaXJlZm94KVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzKTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCBkZWZpbmVzIGdldFVzZXJNZWRpYSBjb25zdHJhaW50c1xuICAgIC8vIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNhcHR1cmUgY29udGVudCBvZiBzY3JlZW5cbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiBjaHJvbWVNZWRpYVNvdXJjZSxcbiAgICAgICAgICAgIG1heFdpZHRoOiBzY3JlZW4ud2lkdGggPiAxOTIwID8gc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgIG1heEhlaWdodDogc2NyZWVuLmhlaWdodCA+IDEwODAgPyBzY3JlZW4uaGVpZ2h0IDogMTA4MFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25hbDogW11cbiAgICB9O1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IHZlcmlmaWVzIGNocm9tZSBleHRlbnNpb24gYXZhaWxhYmlsaXR5XG4gICAgLy8gaWYgaW5zdGFsbGVkIGFuZCBhdmFpbGFibGUgdGhlbiBpdCB3aWxsIGludm9rZSBleHRlbnNpb24gQVBJXG4gICAgLy8gb3RoZXJ3aXNlIGl0IHdpbGwgZmFsbGJhY2sgdG8gY29tbWFuZC1saW5lIGJhc2VkIHNjcmVlbiBjYXB0dXJpbmcgQVBJXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJyAmJiAhc291cmNlSWQpIHtcbiAgICAgICAgaWYgKGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgICAgICAgICAgZ2V0U291cmNlSWRXaXRoQXVkaW8oZnVuY3Rpb24gKHNvdXJjZUlkLCBjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZChmdW5jdGlvbiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHN0YXRlbWVudCBzZXRzIGdldHMgJ3NvdXJjZUlkXCIgYW5kIHNldHMgXCJjaHJvbWVNZWRpYVNvdXJjZUlkXCIgXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpO1xuaW1wb3J0IHV1aWQgPSByZXF1aXJlKCd1dWlkJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uIHtcbiAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgIGF1ZGlvOiBib29sZWFuLFxuICAgICAgICB2aWRlbzogYm9vbGVhblxuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG9uaWNlY2FuZGlkYXRlOiAoZXZlbnQpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQ7XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbTtcbiAgICBtb2RlPzogJ3NlbmRvbmx5JyB8ICdyZWN2b25seScgfCAnc2VuZHJlY3YnO1xuICAgIGlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG5cbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgaWQ6IHN0cmluZztcbiAgICByZW1vdGVDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgbG9jYWxDYW5kaWRhdGVzUXVldWU6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG5cbiAgICBpY2VDYW5kaWRhdGVMaXN0OiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID0gKCEhdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCkgPyB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG4gICAgICAgIHRoaXMuaWQgPSAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdXVpZC52NCgpO1xuXG4gICAgICAgIHRoaXMucGMub25pY2VjYW5kaWRhdGUgPSBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoISFldmVudC5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSA9IGV2ZW50LmNhbmRpZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUucHVzaCg8UlRDSWNlQ2FuZGlkYXRlPnsgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uaWNlY2FuZGlkYXRlKGV2ZW50LmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnc3RhYmxlJykge1xuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPnRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgdGhlXG4gICAgICogcHJvcGVydGllcyByZWNlaXZlZCBpbiB0aGUgY29uc3RydWN0b3IuIEl0IHN0YXJ0cyB0aGUgU0RQIG5lZ290aWF0aW9uXG4gICAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICAgKiBjYWxsYmFjayBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBTRFAgb2ZmZXIsIGluIG9yZGVyIHRvIG9idGFpbiBhbiBTRFBcbiAgICAgKiBhbnN3ZXIgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgICovXG4gICAgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJlamVjdCgnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMjogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgcGMyLmFkZFN0cmVhbSh0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYWNrKHRyYWNrLCB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZnJlZXMgdGhlIHJlc291cmNlcyB1c2VkIGJ5IFdlYlJ0Y1BlZXJcbiAgICAgKi9cbiAgICBkaXNwb3NlKHZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rpc3Bvc2luZyBXZWJSdGNQZWVyJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljLiBMSU1JVEFUSU9OOiBtdXN0IHVzZSBkZXByZWNhdGVkIFdlYlJUQyBBUElcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZW5kZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGMxOiBhbnkgPSB0aGlzLnBjO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiBwYzEuZ2V0TG9jYWxTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoPE1lZGlhU3RyZWFtPnNlbmRlcikuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGMxLnJlbW92ZVN0cmVhbShzZW5kZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgcmVjZWl2ZXJzIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8TWVkaWFTdHJlYW0+cmVjZWl2ZXIpLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbmRlciBvZiB0aGlzLnBjLmdldFNlbmRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXNlbmRlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMucmVtb3ZlVHJhY2soc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVyc1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHRoaXMucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIudHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXhjZXB0aW9uIGRpc3Bvc2luZyB3ZWJydGMgcGVlciAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBvZmZlciwgc2V0cyBpdCBhcyBsb2NhbCBkZXNjcmlwdGlvbiBhbmQgcmV0dXJucyB0aGUgb2ZmZXIgcGFyYW1cbiAgICAgKiB0byBzZW5kIHRvIE9wZW5WaWR1IFNlcnZlciAod2lsbCBiZSB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIG9mIG90aGVyIHBlZXIpXG4gICAgICovXG4gICAgZ2VuZXJhdGVPZmZlcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sIG9mZmVyVmlkZW8gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDb25zdHJhaW50cyBtdXN0IGhhdmUgYm90aCBibG9ja3NcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJBdWRpbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlclZpZGVvKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUlRDUGVlckNvbm5lY3Rpb24gY29uc3RyYWludHM6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaScgJiYgcGxhdGZvcm0udWEhIS5pbmRleE9mKCdTYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgKGV4Y2x1ZGluZyBJb25pYyksIGF0IGxlYXN0IG9uIGlPUyBqdXN0IHNlZW1zIHRvIHN1cHBvcnQgdW5pZmllZCBwbGFuLCB3aGVyZWFzIGluIG90aGVyIGJyb3dzZXJzIGlzIG5vdCB5ZXQgcmVhZHkgYW5kIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcignYXVkaW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAob2ZmZXJWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKCd2aWRlbycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZU9mZmVyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnQ3JlYXRlZCBTRFAgb2ZmZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5jcmVhdGVPZmZlcihjb25zdHJhaW50cykudGhlbihvZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBjLnNldExvY2FsRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsb2NhbERlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRmluYWwgc3RlcCBpbiBTRFAgbmVnb3RpYXRpb24sIHRoZSBwZWVyXG4gICAgICoganVzdCBuZWVkcyB0byBzZXQgdGhlIGFuc3dlciBhcyBpdHMgcmVtb3RlIGRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHJvY2Vzc0Fuc3dlcihzZHBBbnN3ZXI6IHN0cmluZywgbmVlZHNUaW1lb3V0T25Qcm9jZXNzQXN3ZXI6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhbnN3ZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkc1RpbWVvdXRPblByb2Nlc3NBc3dlciAmJiBwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnc2V0UmVtb3RlRGVzY3JpcHRpb24gcnVuIGFmdGVyIHRpbW91dCBmb3IgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcikudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSkudGhlbigoKSA9PiByZXNvbHZlKCkpLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1N0YXRzIHtcblxuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNFbmFibGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0ludGVydmFsSWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBwcml2YXRlIHN0YXRzSW50ZXJ2YWwgPSAxO1xuICAgIHByaXZhdGUgc3RhdHM6IGFueSA9IHtcbiAgICAgICAgaW5ib3VuZDoge1xuICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDAsXG4gICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogMCxcbiAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkgeyB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcblxuICAgICAgICBjb25zdCBlbGFzdGVzdEluc3RydW1lbnRhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdlbGFzdGVzdC1pbnN0cnVtZW50YXRpb24nKTtcblxuICAgICAgICBpZiAoISFlbGFzdGVzdEluc3RydW1lbnRhdGlvbikge1xuICAgICAgICAgICAgLy8gRWxhc1Rlc3QgaW5zdHJ1bWVudGF0aW9uIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVtZW50YXRpb24gPSBKU09OLnBhcnNlKGVsYXN0ZXN0SW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaW50ZXJ2YWw7ICAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIGNvbnNvbGUud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeShpbnN0cnVtZW50YXRpb24pKTtcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludChpbnN0cnVtZW50YXRpb24pO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wV2ViUnRjU3RhdHMoKSB7XG4gICAgICAgIGlmICh0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLndlYlJ0Y1N0YXRzSW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFN0YXRzQWdub3N0aWModGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsb2NhbENhbmRpZGF0ZUlkLCByZW1vdGVDYW5kaWRhdGVJZCwgZ29vZ0NhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbENhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0YXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQudHlwZSA9PT0gJ2xvY2FsY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXNbc3RhdC5pZF0gPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdC50eXBlID09PSAncmVtb3RlY2FuZGlkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ2dvb2dDYW5kaWRhdGVQYWlyJyAmJiAoc3RhdC5nb29nQWN0aXZlQ29ubmVjdGlvbiA9PT0gJ3RydWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpciA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlSWQgPSBzdGF0LmxvY2FsQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZUlkID0gc3RhdC5yZW1vdGVDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlc1tsb2NhbENhbmRpZGF0ZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWZpbmFsTG9jYWxDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5pcEFkZHJlc3MpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gISFjYW5kWzBdID8gY2FuZFswXS5jYW5kaWRhdGUgOiAnRVJST1I6IENhbm5vdCBmaW5kIGxvY2FsIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHNlbnQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgbG9jYWwgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gcmVtb3RlQ2FuZGlkYXRlc1tyZW1vdGVDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnROdW1iZXIpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUucHJpb3JpdHkpID49IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCByZW1vdGUgY2FuZGlkYXRlIGluIGxpc3Qgb2YgcmVjZWl2ZWQgSUNFIGNhbmRpZGF0ZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIHJlbW90ZSBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nQ2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCgnU2VsZWN0ZWQgSUNFIGNhbmRpZGF0ZSBpbmZvIG9ubHkgYXZhaWxhYmxlIGZvciBDaHJvbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBvc3QgPSAoanNvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgaHR0cDogWE1MSHR0cFJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gaW5zdHJ1bWVudGF0aW9uLndlYnJ0Yy5odHRwRW5kcG9pbnQ7XG4gICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cbiAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4geyAvLyBDYWxsIGEgZnVuY3Rpb24gd2hlbiB0aGUgc3RhdGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0ICYmIGh0dHAuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlJ0YyBzdGF0cyBzdWNjZXNzZnVsbHkgc2VudCB0byAnICsgdXJsICsgJyBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodHRwLnNlbmQoanNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZiA9IChzdGF0cykgPT4ge1xuXG4gICAgICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goKHN0YXQpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgoc3RhdC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIGZpcmVmb3ggZW1wdHkgb3V0Ym91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0Lm5hY2tDb3VudCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaXNSZW1vdGUgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pZC5zdGFydHNXaXRoKCdpbmJvdW5kJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LnJlbW90ZUlkLnN0YXJ0c1dpdGgoJ2luYm91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfaW5ib3VuZF8nICsgc3RhdC5tZWRpYVR5cGUgKyAnXycgKyBzdGF0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqaXQgPSBzdGF0LmppdHRlciAqIDEwMDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyOiBqaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAoc3RhdC5wYWNrZXRzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6ICdwYWNrZXRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lm5hY2tDb3VudCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCA9IHN0YXQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0ID0gc3RhdC5wYWNrZXRzTG9zdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjJzogaW5zdHJ1bWVudGF0aW9uLmV4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdldF90eXBlJzogbWV0cmljSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3RhdC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IGluYm91bmQtcnRwIHN0YXRpc3RpY3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnb3V0Ym91bmQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0VuY29kZWQnXSA9IChzdGF0LmZyYW1lc0VuY29kZWQgLSB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdCA9IHN0YXRzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdzc3JjJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2J5dGVzUmVjZWl2ZWQnIGluIHN0YXQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ2F1ZGlvJyAmJiAnYXVkaW9PdXRwdXRMZXZlbCcgaW4gc3RhdCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycgJiYgJ3FwU3VtJyBpbiBzdGF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluYm91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogKHN0YXQuYnl0ZXNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogc3RhdC5nb29nSml0dGVyQnVmZmVyTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogKHN0YXQucGFja2V0c0xvc3QgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNMb3N0KSAvIHRoaXMuc3RhdHNJbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogJ21zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNEZWNvZGVkJ10gPSAoc3RhdC5mcmFtZXNEZWNvZGVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWyduYWNrQ291bnQnXSA9IChzdGF0Lmdvb2dOYWNrc1NlbnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0RlY29kZWQnXSA9ICdmcmFtZXMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snbmFja0NvdW50J10gPSAncGFja2V0cyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5uYWNrQ291bnQgPSBzdGF0Lmdvb2dOYWNrc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1JlY2VpdmVkID0gc3RhdC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkID0gc3RhdC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdieXRlc1NlbnQnIGluIHN0YXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRib3VuZC1ydHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJZCA9ICd3ZWJydGNfb3V0Ym91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAoc3RhdC5ieXRlc1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogKHN0YXQucGFja2V0c1NlbnQgLSB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6ICdieXRlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ2ZyYW1lc0VuY29kZWQnXSA9ICdmcmFtZXMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCA9IHN0YXQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5ieXRlc1NlbnQgPSBzdGF0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzU2VudCA9IHN0YXQucGFja2V0c1NlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHRpbWVzdGFtcCc6IG5ldyBEYXRlKHN0YXQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbSc6ICd3ZWJSdGMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bml0cyc6IHVuaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUG9zdChKU09OLnN0cmluZ2lmeShqc29uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksIGYsIChlcnJvcikgPT4geyBjb25zb2xlLmxvZyhlcnJvcik7IH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdGaXJlZm94JykgIT09IC0xKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZXNwb25zZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlW2tleV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5yZXN1bHQoKS5mb3JFYWNoKHJlcG9ydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICAgIGlkOiByZXBvcnQuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdGF0c0Fnbm9zdGljKHBjLCBzdWNjZXNzQ2IsIGZhaWx1cmVDYikge1xuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZ2V0U3RhdHMgdGFrZXMgYXJncyBpbiBkaWZmZXJlbnQgb3JkZXIgaW4gQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMobnVsbCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9KS5jYXRjaChmYWlsdXJlQ2IpO1xuICAgICAgICB9IGVsc2UgaWYgKChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdDaHJvbWUnKSAhPT0gLTEpIHx8IChwbGF0Zm9ybS5uYW1lIS5pbmRleE9mKCdPcGVyYScpICE9PSAtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIENocm9tZSwgdGhlIGZpcnN0IHR3byBhcmd1bWVudHMgYXJlIHJldmVyc2VkXG4gICAgICAgICAgICByZXR1cm4gcGMuZ2V0U3RhdHMoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVwb3J0ID0gdGhpcy5zdGFuZGFyZGl6ZVJlcG9ydChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc0NiKHJlcG9ydCk7XG4gICAgICAgICAgICB9LCBudWxsLCBmYWlsdXJlQ2IpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19 diff --git a/openvidu-mvc-node/public/openvidu-browser-2.11.0.js b/openvidu-mvc-node/public/openvidu-browser-2.11.0.js new file mode 100644 index 000000000..375ee95ed --- /dev/null +++ b/openvidu-mvc-node/public/openvidu-browser-2.11.0.js @@ -0,0 +1,8661 @@ +(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 1) + 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('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; + } + return false; + } + + handler = events[type]; + + if (!handler) + return false; + + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { + // fast cases + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; + // slower + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (!existing) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + } else { + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } + } + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (!events) + return []; + + var evlistener = events[type]; + if (!evlistener) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; +} + +},{}],2:[function(require,module,exports){ +/* jshint node: true */ +'use strict'; + +var normalice = require('normalice'); + +/** + # freeice + + The `freeice` module is a simple way of getting random STUN or TURN server + for your WebRTC application. The list of servers (just STUN at this stage) + were sourced from this [gist](https://gist.github.com/zziuni/3741933). + + ## Example Use + + The following demonstrates how you can use `freeice` with + [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect): + + <<< examples/quickconnect.js + + As the `freeice` module generates ice servers in a list compliant with the + WebRTC spec you will be able to use it with raw `RTCPeerConnection` + constructors and other WebRTC libraries. + + ## Hey, don't use my STUN/TURN server! + + If for some reason your free STUN or TURN server ends up in the + list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or + [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json)) + that is used in this module, you can feel + free to open an issue on this repository and those servers will be removed + within 24 hours (or sooner). This is the quickest and probably the most + polite way to have something removed (and provides us some visibility + if someone opens a pull request requesting that a server is added). + + ## Please add my server! + + If you have a server that you wish to add to the list, that's awesome! I'm + sure I speak on behalf of a whole pile of WebRTC developers who say thanks. + To get it into the list, feel free to either open a pull request or if you + find that process a bit daunting then just create an issue requesting + the addition of the server (make sure you provide all the details, and if + you have a Terms of Service then including that in the PR/issue would be + awesome). + + ## I know of a free server, can I add it? + + Sure, if you do your homework and make sure it is ok to use (I'm currently + in the process of reviewing the terms of those STUN servers included from + the original list). If it's ok to go, then please see the previous entry + for how to add it. + + ## Current List of Servers + + * current as at the time of last `README.md` file generation + + ### STUN + + <<< stun.json + + ### TURN + + <<< turn.json + +**/ + +var freeice = function(opts) { + // if a list of servers has been provided, then use it instead of defaults + var servers = { + stun: (opts || {}).stun || require('./stun.json'), + turn: (opts || {}).turn || require('./turn.json') + }; + + var stunCount = (opts || {}).stunCount || 2; + var turnCount = (opts || {}).turnCount || 0; + var selected; + + function getServers(type, count) { + var out = []; + var input = [].concat(servers[type]); + var idx; + + while (input.length && out.length < count) { + idx = (Math.random() * input.length) | 0; + out = out.concat(input.splice(idx, 1)); + } + + return out.map(function(url) { + //If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up + if ((typeof url !== 'string') && (! (url instanceof String))) { + return url; + } else { + return normalice(type + ':' + url); + } + }); + } + + // add stun servers + selected = [].concat(getServers('stun', stunCount)); + + if (turnCount) { + selected = selected.concat(getServers('turn', turnCount)); + } + + return selected; +}; + +module.exports = freeice; +},{"./stun.json":3,"./turn.json":4,"normalice":7}],3:[function(require,module,exports){ +module.exports=[ + "stun.l.google.com:19302", + "stun1.l.google.com:19302", + "stun2.l.google.com:19302", + "stun3.l.google.com:19302", + "stun4.l.google.com:19302", + "stun.ekiga.net", + "stun.ideasip.com", + "stun.schlund.de", + "stun.stunprotocol.org:3478", + "stun.voiparound.com", + "stun.voipbuster.com", + "stun.voipstunt.com", + "stun.voxgratia.org" +] + +},{}],4:[function(require,module,exports){ +module.exports=[] + +},{}],5:[function(require,module,exports){ +var WildEmitter = require('wildemitter'); + +function getMaxVolume (analyser, fftBins) { + var maxVolume = -Infinity; + analyser.getFloatFrequencyData(fftBins); + + for(var i=4, ii=fftBins.length; i < ii; i++) { + if (fftBins[i] > maxVolume && fftBins[i] < 0) { + maxVolume = fftBins[i]; + } + }; + + return maxVolume; +} + + +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} +// use a single audio context due to hardware limits +var audioContext = null; +module.exports = function(stream, options) { + var harker = new WildEmitter(); + + // make it not break in non-supported browsers + if (!audioContextType) return harker; + + //Config + var options = options || {}, + smoothing = (options.smoothing || 0.1), + interval = (options.interval || 50), + threshold = options.threshold, + play = options.play, + history = options.history || 10, + running = true; + + // Ensure that just a single AudioContext is internally created + audioContext = options.audioContext || audioContext || new audioContextType(); + + var sourceNode, fftBins, analyser; + + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + analyser.smoothingTimeConstant = smoothing; + fftBins = new Float32Array(analyser.frequencyBinCount); + + if (stream.jquery) stream = stream[0]; + if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { + //Audio Tag + sourceNode = audioContext.createMediaElementSource(stream); + if (typeof play === 'undefined') play = true; + threshold = threshold || -50; + } else { + //WebRTC Stream + sourceNode = audioContext.createMediaStreamSource(stream); + threshold = threshold || -50; + } + + sourceNode.connect(analyser); + if (play) analyser.connect(audioContext.destination); + + harker.speaking = false; + + harker.suspend = function() { + return audioContext.suspend(); + } + harker.resume = function() { + return audioContext.resume(); + } + Object.defineProperty(harker, 'state', { get: function() { + return audioContext.state; + }}); + audioContext.onstatechange = function() { + harker.emit('state_change', audioContext.state); + } + + harker.setThreshold = function(t) { + threshold = t; + }; + + harker.setInterval = function(i) { + interval = i; + }; + + harker.stop = function() { + running = false; + harker.emit('volume_change', -100, threshold); + if (harker.speaking) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + analyser.disconnect(); + sourceNode.disconnect(); + }; + harker.speakingHistory = []; + for (var i = 0; i < history; i++) { + harker.speakingHistory.push(0); + } + + // Poll the analyser node to determine if speaking + // and emit events if changed + var looper = function() { + setTimeout(function() { + + //check if stop has been called + if(!running) { + return; + } + + var currentVolume = getMaxVolume(analyser, fftBins); + + harker.emit('volume_change', currentVolume, threshold); + + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); + + looper(); + }, interval); + }; + looper(); + + return harker; +} + +},{"wildemitter":14}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (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) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + +},{}],7:[function(require,module,exports){ +/** + # normalice + + Normalize an ice server configuration object (or plain old string) into a format + that is usable in all browsers supporting WebRTC. Primarily this module is designed + to help with the transition of the `url` attribute of the configuration object to + the `urls` attribute. + + ## Example Usage + + <<< examples/simple.js + +**/ + +var protocols = [ + 'stun:', + 'turn:' +]; + +module.exports = function(input) { + var url = (input || {}).url || input; + var protocol; + var parts; + var output = {}; + + // if we don't have a string url, then allow the input to passthrough + if (typeof url != 'string' && (! (url instanceof String))) { + return input; + } + + // trim the url string, and convert to an array + url = url.trim(); + + // if the protocol is not known, then passthrough + protocol = protocols[protocols.indexOf(url.slice(0, 5))]; + if (! protocol) { + return input; + } + + // now let's attack the remaining url parts + url = url.slice(5); + parts = url.split('@'); + + output.username = input.username; + output.credential = input.credential; + // if we have an authentication part, then set the credentials + if (parts.length > 1) { + url = parts[1]; + parts = parts[0].split(':'); + + // add the output credential and username + output.username = parts[0]; + output.credential = (input || {}).credential || parts[1] || ''; + } + + output.url = protocol + url; + output.urls = [ output.url ]; + + return output; +}; + +},{}],8:[function(require,module,exports){ +(function (global){ +/*! + * Platform.js + * Copyright 2014-2018 Benjamin Tan + * Copyright 2011-2013 John-David Dalton + * Available under MIT license + */ +;(function() { + 'use strict'; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used as a reference to the global object. */ + var root = (objectTypes[typeof window] && window) || this; + + /** Backup possible global object. */ + var oldRoot = root; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** + * Used as the maximum length of an array-like object. + * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ + var maxSafeInteger = Math.pow(2, 53) - 1; + + /** Regular expression to detect Opera. */ + var reOpera = /\bOpera/; + + /** Possible global object. */ + var thisBinding = this; + + /** Used for native method references. */ + var objectProto = Object.prototype; + + /** Used to check for own properties of an object. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to resolve the internal `[[Class]]` of values. */ + var toString = objectProto.toString; + + /*--------------------------------------------------------------------------*/ + + /** + * Capitalizes a string value. + * + * @private + * @param {string} string The string to capitalize. + * @returns {string} The capitalized string. + */ + function capitalize(string) { + string = String(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + /** + * A utility function to clean up the OS name. + * + * @private + * @param {string} os The OS name to clean up. + * @param {string} [pattern] A `RegExp` pattern matching the OS name. + * @param {string} [label] A label for the OS. + */ + function cleanupOS(os, pattern, label) { + // Platform tokens are defined at: + // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx + var data = { + '10.0': '10', + '6.4': '10 Technical Preview', + '6.3': '8.1', + '6.2': '8', + '6.1': 'Server 2008 R2 / 7', + '6.0': 'Server 2008 / Vista', + '5.2': 'Server 2003 / XP 64-bit', + '5.1': 'XP', + '5.01': '2000 SP1', + '5.0': '2000', + '4.0': 'NT', + '4.90': 'ME' + }; + // Detect Windows version from platform tokens. + if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && + (data = data[/[\d.]+$/.exec(os)])) { + os = 'Windows ' + data; + } + // Correct character case and cleanup string. + os = String(os); + + if (pattern && label) { + os = os.replace(RegExp(pattern, 'i'), label); + } + + os = format( + os.replace(/ ce$/i, ' CE') + .replace(/\bhpw/i, 'web') + .replace(/\bMacintosh\b/, 'Mac OS') + .replace(/_PowerPC\b/i, ' OS') + .replace(/\b(OS X) [^ \d]+/i, '$1') + .replace(/\bMac (OS X)\b/, '$1') + .replace(/\/(\d)/, ' $1') + .replace(/_/g, '.') + .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') + .replace(/\bx86\.64\b/gi, 'x86_64') + .replace(/\b(Windows Phone) OS\b/, '$1') + .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') + .split(' on ')[0] + ); + + return os; + } + + /** + * An iteration utility for arrays and objects. + * + * @private + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + */ + function each(object, callback) { + var index = -1, + length = object ? object.length : 0; + + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { + while (++index < length) { + callback(object[index], index, object); + } + } else { + forOwn(object, callback); + } + } + + /** + * Trim and conditionally capitalize string values. + * + * @private + * @param {string} string The string to format. + * @returns {string} The formatted string. + */ + function format(string) { + string = trim(string); + return /^(?:webOS|i(?:OS|P))/.test(string) + ? string + : capitalize(string); + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + */ + function forOwn(object, callback) { + for (var key in object) { + if (hasOwnProperty.call(object, key)) { + callback(object[key], key, object); + } + } + } + + /** + * Gets the internal `[[Class]]` of a value. + * + * @private + * @param {*} value The value. + * @returns {string} The `[[Class]]`. + */ + function getClassOf(value) { + return value == null + ? capitalize(value) + : toString.call(value).slice(8, -1); + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of "object", "function", or "unknown". + * + * @private + * @param {*} object The owner of the property. + * @param {string} property The property to check. + * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. + * + * @private + * @param {string} string The string to qualify. + * @returns {string} The qualified string. + */ + function qualify(string) { + return String(string).replace(/([ -])(?!$)/g, '$1?'); + } + + /** + * A bare-bones `Array#reduce` like utility function. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @returns {*} The accumulated result. + */ + function reduce(array, callback) { + var accumulator = null; + each(array, function(value, index) { + accumulator = callback(accumulator, value, index, array); + }); + return accumulator; + } + + /** + * Removes leading and trailing whitespace from a string. + * + * @private + * @param {string} string The string to trim. + * @returns {string} The trimmed string. + */ + function trim(string) { + return String(string).replace(/^ +| +$/g, ''); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new platform object. + * + * @memberOf platform + * @param {Object|string} [ua=navigator.userAgent] The user agent string or + * context object. + * @returns {Object} A platform object. + */ + function parse(ua) { + + /** The environment context object. */ + var context = root; + + /** Used to flag when a custom context is provided. */ + var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; + + // Juggle arguments. + if (isCustomContext) { + context = ua; + ua = null; + } + + /** Browser navigator object. */ + var nav = context.navigator || {}; + + /** Browser user agent string. */ + var userAgent = nav.userAgent || ''; + + ua || (ua = userAgent); + + /** Used to flag when `thisBinding` is the [ModuleScope]. */ + var isModuleScope = isCustomContext || thisBinding == oldRoot; + + /** Used to detect if browser is like Chrome. */ + var likeChrome = isCustomContext + ? !!nav.likeChrome + : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); + + /** Internal `[[Class]]` value shortcuts. */ + var objectClass = 'Object', + airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', + enviroClass = isCustomContext ? objectClass : 'Environment', + javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), + phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; + + /** Detect Java environments. */ + var java = /\bJava/.test(javaClass) && context.java; + + /** Detect Rhino. */ + var rhino = java && getClassOf(context.environment) == enviroClass; + + /** A character to represent alpha. */ + var alpha = java ? 'a' : '\u03b1'; + + /** A character to represent beta. */ + var beta = java ? 'b' : '\u03b2'; + + /** Browser document object. */ + var doc = context.document || {}; + + /** + * Detect Opera browser (Presto-based). + * http://www.howtocreate.co.uk/operaStuff/operaObject.html + * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini + */ + var opera = context.operamini || context.opera; + + /** Opera `[[Class]]`. */ + var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) + ? operaClass + : (opera = null); + + /*------------------------------------------------------------------------*/ + + /** Temporary variable used over the script's lifetime. */ + var data; + + /** The CPU architecture. */ + var arch = ua; + + /** Platform description array. */ + var description = []; + + /** Platform alpha/beta indicator. */ + var prerelease = null; + + /** A flag to indicate that environment features should be used to resolve the platform. */ + var useFeatures = ua == userAgent; + + /** The browser/environment version. */ + var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); + + /** A flag to indicate if the OS ends with "/ Version" */ + var isSpecialCasedOS; + + /* Detectable layout engines (order is important). */ + var layout = getLayout([ + { 'label': 'EdgeHTML', 'pattern': 'Edge' }, + 'Trident', + { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, + 'iCab', + 'Presto', + 'NetFront', + 'Tasman', + 'KHTML', + 'Gecko' + ]); + + /* Detectable browser names (order is important). */ + var name = getName([ + 'Adobe AIR', + 'Arora', + 'Avant Browser', + 'Breach', + 'Camino', + 'Electron', + 'Epiphany', + 'Fennec', + 'Flock', + 'Galeon', + 'GreenBrowser', + 'iCab', + 'Iceweasel', + 'K-Meleon', + 'Konqueror', + 'Lunascape', + 'Maxthon', + { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, + 'Midori', + 'Nook Browser', + 'PaleMoon', + 'PhantomJS', + 'Raven', + 'Rekonq', + 'RockMelt', + { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, + 'SeaMonkey', + { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Sleipnir', + 'SlimBrowser', + { 'label': 'SRWare Iron', 'pattern': 'Iron' }, + 'Sunrise', + 'Swiftfox', + 'Waterfox', + 'WebPositive', + 'Opera Mini', + { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, + 'Opera', + { 'label': 'Opera', 'pattern': 'OPR' }, + 'Chrome', + { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, + { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, + { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, + { 'label': 'IE', 'pattern': 'IEMobile' }, + { 'label': 'IE', 'pattern': 'MSIE' }, + 'Safari' + ]); + + /* Detectable products (order is important). */ + var product = getProduct([ + { 'label': 'BlackBerry', 'pattern': 'BB10' }, + 'BlackBerry', + { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, + { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, + { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, + { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, + { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, + { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, + { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, + { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, + { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, + 'Google TV', + 'Lumia', + 'iPad', + 'iPod', + 'iPhone', + 'Kindle', + { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, + 'Nexus', + 'Nook', + 'PlayBook', + 'PlayStation Vita', + 'PlayStation', + 'TouchPad', + 'Transformer', + { 'label': 'Wii U', 'pattern': 'WiiU' }, + 'Wii', + 'Xbox One', + { 'label': 'Xbox 360', 'pattern': 'Xbox' }, + 'Xoom' + ]); + + /* Detectable manufacturers. */ + var manufacturer = getManufacturer({ + 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, + 'Archos': {}, + 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, + 'Asus': { 'Transformer': 1 }, + 'Barnes & Noble': { 'Nook': 1 }, + 'BlackBerry': { 'PlayBook': 1 }, + 'Google': { 'Google TV': 1, 'Nexus': 1 }, + 'HP': { 'TouchPad': 1 }, + 'HTC': {}, + 'LG': {}, + 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, + 'Motorola': { 'Xoom': 1 }, + 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, + 'Nokia': { 'Lumia': 1 }, + 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, + 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } + }); + + /* Detectable operating systems (order is important). */ + var os = getOS([ + 'Windows Phone', + 'Android', + 'CentOS', + { 'label': 'Chrome OS', 'pattern': 'CrOS' }, + 'Debian', + 'Fedora', + 'FreeBSD', + 'Gentoo', + 'Haiku', + 'Kubuntu', + 'Linux Mint', + 'OpenBSD', + 'Red Hat', + 'SuSE', + 'Ubuntu', + 'Xubuntu', + 'Cygwin', + 'Symbian OS', + 'hpwOS', + 'webOS ', + 'webOS', + 'Tablet OS', + 'Tizen', + 'Linux', + 'Mac OS X', + 'Macintosh', + 'Mac', + 'Windows 98;', + 'Windows ' + ]); + + /*------------------------------------------------------------------------*/ + + /** + * Picks the layout engine from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected layout engine. + */ + function getLayout(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the manufacturer from an array of guesses. + * + * @private + * @param {Array} guesses An object of guesses. + * @returns {null|string} The detected manufacturer. + */ + function getManufacturer(guesses) { + return reduce(guesses, function(result, value, key) { + // Lookup the manufacturer by product or scan the UA for the manufacturer. + return result || ( + value[product] || + value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || + RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) + ) && key; + }); + } + + /** + * Picks the browser name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected browser name. + */ + function getName(guesses) { + return reduce(guesses, function(result, guess) { + return result || RegExp('\\b' + ( + guess.pattern || qualify(guess) + ) + '\\b', 'i').exec(ua) && (guess.label || guess); + }); + } + + /** + * Picks the OS name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected OS name. + */ + function getOS(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) + )) { + result = cleanupOS(result, pattern, guess.label || guess); + } + return result; + }); + } + + /** + * Picks the product name from an array of guesses. + * + * @private + * @param {Array} guesses An array of guesses. + * @returns {null|string} The detected product name. + */ + function getProduct(guesses) { + return reduce(guesses, function(result, guess) { + var pattern = guess.pattern || qualify(guess); + if (!result && (result = + RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || + RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || + RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) + )) { + // Split by forward slash and append product version if needed. + if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { + result[0] += ' ' + result[1]; + } + // Correct character case and cleanup string. + guess = guess.label || guess; + result = format(result[0] + .replace(RegExp(pattern, 'i'), guess) + .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') + .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); + } + return result; + }); + } + + /** + * Resolves the version using an array of UA patterns. + * + * @private + * @param {Array} patterns An array of UA patterns. + * @returns {null|string} The detected version. + */ + function getVersion(patterns) { + return reduce(patterns, function(result, pattern) { + return result || (RegExp(pattern + + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; + }); + } + + /** + * Returns `platform.description` when the platform object is coerced to a string. + * + * @name toString + * @memberOf platform + * @returns {string} Returns `platform.description` if available, else an empty string. + */ + function toStringPlatform() { + return this.description || ''; + } + + /*------------------------------------------------------------------------*/ + + // Convert layout to an array so we can add extra details. + layout && (layout = [layout]); + + // Detect product names that contain their manufacturer's name. + if (manufacturer && !product) { + product = getProduct([manufacturer]); + } + // Clean up Google TV. + if ((data = /\bGoogle TV\b/.exec(product))) { + product = data[0]; + } + // Detect simulators. + if (/\bSimulator\b/i.test(ua)) { + product = (product ? product + ' ' : '') + 'Simulator'; + } + // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. + if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { + description.push('running in Turbo/Uncompressed mode'); + } + // Detect IE Mobile 11. + if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { + data = parse(ua.replace(/like iPhone OS/, '')); + manufacturer = data.manufacturer; + product = data.product; + } + // Detect iOS. + else if (/^iP/.test(product)) { + name || (name = 'Safari'); + os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) + ? ' ' + data[1].replace(/_/g, '.') + : ''); + } + // Detect Kubuntu. + else if (name == 'Konqueror' && !/buntu/i.test(os)) { + os = 'Kubuntu'; + } + // Detect Android browsers. + else if ((manufacturer && manufacturer != 'Google' && + ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || + (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { + name = 'Android Browser'; + os = /\bAndroid\b/.test(os) ? os : 'Android'; + } + // Detect Silk desktop/accelerated modes. + else if (name == 'Silk') { + if (!/\bMobi/i.test(ua)) { + os = 'Android'; + description.unshift('desktop mode'); + } + if (/Accelerated *= *true/i.test(ua)) { + description.unshift('accelerated'); + } + } + // Detect PaleMoon identifying as Firefox. + else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { + description.push('identifying as Firefox ' + data[1]); + } + // Detect Firefox OS and products running Firefox. + else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { + os || (os = 'Firefox OS'); + product || (product = data[1]); + } + // Detect false positives for Firefox/Safari. + else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { + // Escape the `/` for Firefox 1. + if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { + // Clear name of false positives. + name = null; + } + // Reassign a generic name. + if ((data = product || manufacturer || os) && + (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { + name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; + } + } + // Add Chrome version to description for Electron. + else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { + description.push('Chromium ' + data); + } + // Detect non-Opera (Presto-based) versions (order is important). + if (!version) { + version = getVersion([ + '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', + 'Version', + qualify(name), + '(?:Firefox|Minefield|NetFront)' + ]); + } + // Detect stubborn layout engines. + if ((data = + layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || + /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || + /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || + !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || + layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' + )) { + layout = [data]; + } + // Detect Windows Phone 7 desktop mode. + if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { + name += ' Mobile'; + os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); + description.unshift('desktop mode'); + } + // Detect Windows Phone 8.x desktop mode. + else if (/\bWPDesktop\b/i.test(ua)) { + name = 'IE Mobile'; + os = 'Windows Phone 8.x'; + description.unshift('desktop mode'); + version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); + } + // Detect IE 11 identifying as other browsers. + else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { + if (name) { + description.push('identifying as ' + name + (version ? ' ' + version : '')); + } + name = 'IE'; + version = data[1]; + } + // Leverage environment features. + if (useFeatures) { + // Detect server-side environments. + // Rhino has a global function while others have a global object. + if (isHostType(context, 'global')) { + if (java) { + data = java.lang.System; + arch = data.getProperty('os.arch'); + os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); + } + if (rhino) { + try { + version = context.require('ringo/engine').version.join('.'); + name = 'RingoJS'; + } catch(e) { + if ((data = context.system) && data.global.system == context.system) { + name = 'Narwhal'; + os || (os = data[0].os || null); + } + } + if (!name) { + name = 'Rhino'; + } + } + else if ( + typeof context.process == 'object' && !context.process.browser && + (data = context.process) + ) { + if (typeof data.versions == 'object') { + if (typeof data.versions.electron == 'string') { + description.push('Node ' + data.versions.node); + name = 'Electron'; + version = data.versions.electron; + } else if (typeof data.versions.nw == 'string') { + description.push('Chromium ' + version, 'Node ' + data.versions.node); + name = 'NW.js'; + version = data.versions.nw; + } + } + if (!name) { + name = 'Node.js'; + arch = data.arch; + os = data.platform; + version = /[\d.]+/.exec(data.version); + version = version ? version[0] : null; + } + } + } + // Detect Adobe AIR. + else if (getClassOf((data = context.runtime)) == airRuntimeClass) { + name = 'Adobe AIR'; + os = data.flash.system.Capabilities.os; + } + // Detect PhantomJS. + else if (getClassOf((data = context.phantom)) == phantomClass) { + name = 'PhantomJS'; + version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); + } + // Detect IE compatibility modes. + else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { + // We're in compatibility mode when the Trident version + 4 doesn't + // equal the document mode. + version = [version, doc.documentMode]; + if ((data = +data[1] + 4) != version[1]) { + description.push('IE ' + version[1] + ' mode'); + layout && (layout[1] = ''); + version[1] = data; + } + version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; + } + // Detect IE 11 masking as other browsers. + else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { + description.push('masking as ' + name + ' ' + version); + name = 'IE'; + version = '11.0'; + layout = ['Trident']; + os = 'Windows'; + } + os = os && format(os); + } + // Detect prerelease phases. + if (version && (data = + /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || + /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || + /\bMinefield\b/i.test(ua) && 'a' + )) { + prerelease = /b/i.test(data) ? 'beta' : 'alpha'; + version = version.replace(RegExp(data + '\\+?$'), '') + + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); + } + // Detect Firefox Mobile. + if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { + name = 'Firefox Mobile'; + } + // Obscure Maxthon's unreliable version. + else if (name == 'Maxthon' && version) { + version = version.replace(/\.[\d.]+/, '.x'); + } + // Detect Xbox 360 and Xbox One. + else if (/\bXbox\b/i.test(product)) { + if (product == 'Xbox 360') { + os = null; + } + if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { + description.unshift('mobile mode'); + } + } + // Add mobile postfix. + else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && + (os == 'Windows CE' || /Mobi/i.test(ua))) { + name += ' Mobile'; + } + // Detect IE platform preview. + else if (name == 'IE' && useFeatures) { + try { + if (context.external === null) { + description.unshift('platform preview'); + } + } catch(e) { + description.unshift('embedded'); + } + } + // Detect BlackBerry OS version. + // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp + else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = + (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || + version + )) { + data = [data, /BB10/.test(ua)]; + os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; + version = null; + } + // Detect Opera identifying/masking itself as another browser. + // http://www.opera.com/support/kb/view/843/ + else if (this != forOwn && product != 'Wii' && ( + (useFeatures && opera) || + (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || + (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || + (name == 'IE' && ( + (os && !/^Win/.test(os) && version > 5.5) || + /\bWindows XP\b/.test(os) && version > 8 || + version == 8 && !/\bTrident\b/.test(ua) + )) + ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { + // When "identifying", the UA contains both Opera and the other browser's name. + data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); + if (reOpera.test(name)) { + if (/\bIE\b/.test(data) && os == 'Mac OS') { + os = null; + } + data = 'identify' + data; + } + // When "masking", the UA contains only the other browser's name. + else { + data = 'mask' + data; + if (operaClass) { + name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); + } else { + name = 'Opera'; + } + if (/\bIE\b/.test(data)) { + os = null; + } + if (!useFeatures) { + version = null; + } + } + layout = ['Presto']; + description.push(data); + } + // Detect WebKit Nightly and approximate Chrome/Safari versions. + if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + // Correct build number for numeric comparison. + // (e.g. "532.5" becomes "532.05") + data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; + // Nightly builds are postfixed with a "+". + if (name == 'Safari' && data[1].slice(-1) == '+') { + name = 'WebKit Nightly'; + prerelease = 'alpha'; + version = data[1].slice(0, -1); + } + // Clear incorrect browser versions. + else if (version == data[1] || + version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { + version = null; + } + // Use the full Chrome version when available. + data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; + // Detect Blink layout engine. + if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { + layout = ['Blink']; + } + // Detect JavaScriptCore. + // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi + if (!useFeatures || (!likeChrome && !data[1])) { + layout && (layout[1] = 'like Safari'); + data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); + } else { + layout && (layout[1] = 'like Chrome'); + data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); + } + // Add the postfix of ".x" or "+" for approximate versions. + layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); + // Obscure version for some Safari 1-2 releases. + if (name == 'Safari' && (!version || parseInt(version) > 45)) { + version = data; + } + } + // Detect Opera desktop modes. + if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { + name += ' '; + description.unshift('desktop mode'); + if (data == 'zvav') { + name += 'Mini'; + version = null; + } else { + name += 'Mobile'; + } + os = os.replace(RegExp(' *' + data + '$'), ''); + } + // Detect Chrome desktop mode. + else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { + description.unshift('desktop mode'); + name = 'Chrome Mobile'; + version = null; + + if (/\bOS X\b/.test(os)) { + manufacturer = 'Apple'; + os = 'iOS 4.3+'; + } else { + os = null; + } + } + // Strip incorrect OS versions. + if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && + ua.indexOf('/' + data + '-') > -1) { + os = trim(os.replace(data, '')); + } + // Add layout engine. + if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( + /Browser|Lunascape|Maxthon/.test(name) || + name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || + /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { + // Don't add layout details to description if they are falsey. + (data = layout[layout.length - 1]) && description.push(data); + } + // Combine contextual information. + if (description.length) { + description = ['(' + description.join('; ') + ')']; + } + // Append manufacturer to description. + if (manufacturer && product && product.indexOf(manufacturer) < 0) { + description.push('on ' + manufacturer); + } + // Append product to description. + if (product) { + description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); + } + // Parse the OS into an object. + if (os) { + data = / ([\d.+]+)$/.exec(os); + isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; + os = { + 'architecture': 32, + 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, + 'version': data ? data[1] : null, + 'toString': function() { + var version = this.version; + return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); + } + }; + } + // Add browser/OS architecture. + if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { + if (os) { + os.architecture = 64; + os.family = os.family.replace(RegExp(' *' + data), ''); + } + if ( + name && (/\bWOW64\b/i.test(ua) || + (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) + ) { + description.unshift('32-bit'); + } + } + // Chrome 39 and above on OS X is always 64-bit. + else if ( + os && /^OS X/.test(os.family) && + name == 'Chrome' && parseFloat(version) >= 39 + ) { + os.architecture = 64; + } + + ua || (ua = null); + + /*------------------------------------------------------------------------*/ + + /** + * The platform object. + * + * @name platform + * @type Object + */ + var platform = {}; + + /** + * The platform description. + * + * @memberOf platform + * @type string|null + */ + platform.description = ua; + + /** + * The name of the browser's layout engine. + * + * The list of common layout engines include: + * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" + * + * @memberOf platform + * @type string|null + */ + platform.layout = layout && layout[0]; + + /** + * The name of the product's manufacturer. + * + * The list of manufacturers include: + * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", + * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", + * "Nokia", "Samsung" and "Sony" + * + * @memberOf platform + * @type string|null + */ + platform.manufacturer = manufacturer; + + /** + * The name of the browser/environment. + * + * The list of common browser names include: + * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", + * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", + * "Opera Mini" and "Opera" + * + * Mobile versions of some browsers have "Mobile" appended to their name: + * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" + * + * @memberOf platform + * @type string|null + */ + platform.name = name; + + /** + * The alpha/beta release indicator. + * + * @memberOf platform + * @type string|null + */ + platform.prerelease = prerelease; + + /** + * The name of the product hosting the browser. + * + * The list of common products include: + * + * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", + * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" + * + * @memberOf platform + * @type string|null + */ + platform.product = product; + + /** + * The browser's user agent string. + * + * @memberOf platform + * @type string|null + */ + platform.ua = ua; + + /** + * The browser/environment version. + * + * @memberOf platform + * @type string|null + */ + platform.version = name && version; + + /** + * The name of the operating system. + * + * @memberOf platform + * @type Object + */ + platform.os = os || { + + /** + * The CPU architecture the OS is built for. + * + * @memberOf platform.os + * @type number|null + */ + 'architecture': null, + + /** + * The family of the OS. + * + * Common values include: + * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", + * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", + * "Android", "iOS" and "Windows Phone" + * + * @memberOf platform.os + * @type string|null + */ + 'family': null, + + /** + * The version of the OS. + * + * @memberOf platform.os + * @type string|null + */ + 'version': null, + + /** + * Returns the OS string. + * + * @memberOf platform.os + * @returns {string} The OS string. + */ + 'toString': function() { return 'null'; } + }; + + platform.parse = parse; + platform.toString = toStringPlatform; + + if (platform.version) { + description.unshift(version); + } + if (platform.name) { + description.unshift(name); + } + if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { + description.push(product ? '(' + os + ')' : 'on ' + os); + } + if (description.length) { + platform.description = description.join(' '); + } + return platform; + } + + /*--------------------------------------------------------------------------*/ + + // Export platform. + var platform = parse(); + + // Some AMD build optimizers, like r.js, check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose platform on the global object to prevent errors when platform is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + root.platform = platform; + + // Define as an anonymous module so platform can be aliased through path mapping. + define(function() { + return platform; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for CommonJS support. + forOwn(platform, function(value, key) { + freeExports[key] = value; + }); + } + else { + // Export to the global object. + root.platform = platform; + } +}.call(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],9:[function(require,module,exports){ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; + +},{"./v1":12,"./v4":13}],10:[function(require,module,exports){ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + +},{}],11:[function(require,module,exports){ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} + +},{}],12:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],13:[function(require,module,exports){ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + +},{"./lib/bytesToUuid":10,"./lib/rng":11}],14:[function(require,module,exports){ +/* +WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based +on @visionmedia's Emitter from UI Kit. + +Why? I wanted it standalone. + +I also wanted support for wildcard emitters like this: + +emitter.on('*', function (eventName, other, event, payloads) { + +}); + +emitter.on('somenamespace*', function (eventName, payloads) { + +}); + +Please note that callbacks triggered by wildcard registered events also get +the event name as the first argument. +*/ + +module.exports = WildEmitter; + +function WildEmitter() { } + +WildEmitter.mixin = function (constructor) { + var prototype = constructor.prototype || constructor; + + prototype.isWildEmitter= true; + + // Listen on the given `event` with `fn`. Store a group name if present. + prototype.on = function (event, groupName, fn) { + this.callbacks = this.callbacks || {}; + var hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + func._groupName = group; + (this.callbacks[event] = this.callbacks[event] || []).push(func); + return this; + }; + + // Adds an `event` listener that will be invoked a single + // time then automatically removed. + prototype.once = function (event, groupName, fn) { + var self = this, + hasGroup = (arguments.length === 3), + group = hasGroup ? arguments[1] : undefined, + func = hasGroup ? arguments[2] : arguments[1]; + function on() { + self.off(event, on); + func.apply(this, arguments); + } + this.on(event, group, on); + return this; + }; + + // Unbinds an entire group + prototype.releaseGroup = function (groupName) { + this.callbacks = this.callbacks || {}; + var item, i, len, handlers; + for (item in this.callbacks) { + handlers = this.callbacks[item]; + for (i = 0, len = handlers.length; i < len; i++) { + if (handlers[i]._groupName === groupName) { + //console.log('removing'); + // remove it and shorten the array we're looping through + handlers.splice(i, 1); + i--; + len--; + } + } + } + return this; + }; + + // Remove the given callback for `event` or all + // registered callbacks. + prototype.off = function (event, fn) { + this.callbacks = this.callbacks || {}; + var callbacks = this.callbacks[event], + i; + + if (!callbacks) return this; + + // remove all handlers + if (arguments.length === 1) { + delete this.callbacks[event]; + return this; + } + + // remove specific handler + i = callbacks.indexOf(fn); + if (i !== -1) { + callbacks.splice(i, 1); + if (callbacks.length === 0) { + delete this.callbacks[event]; + } + } + return this; + }; + + /// Emit `event` with the given args. + // also calls any `*` handlers + prototype.emit = function (event) { + this.callbacks = this.callbacks || {}; + var args = [].slice.call(arguments, 1), + callbacks = this.callbacks[event], + specialCallbacks = this.getWildcardCallbacks(event), + i, + len, + item, + listeners; + + if (callbacks) { + listeners = callbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, args); + } + } + + if (specialCallbacks) { + len = specialCallbacks.length; + listeners = specialCallbacks.slice(); + for (i = 0, len = listeners.length; i < len; ++i) { + if (!listeners[i]) { + break; + } + listeners[i].apply(this, [event].concat(args)); + } + } + + return this; + }; + + // Helper for for finding special wildcard event handlers that match the event + prototype.getWildcardCallbacks = function (eventName) { + this.callbacks = this.callbacks || {}; + var item, + split, + result = []; + + for (item in this.callbacks) { + split = item.split('*'); + if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) { + result = result.concat(this.callbacks[item]); + } + } + return result; + }; + +}; + +WildEmitter.mixin(WildEmitter); + +},{}],15:[function(require,module,exports){ +/*! + * EventEmitter v5.2.6 - git.io/ee + * Unlicense - http://unlicense.org/ + * Oliver Caldwell - https://oli.me.uk/ + * @preserve + */ + +;(function (exports) { + 'use strict'; + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in its storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + function isValidListener (listener) { + if (typeof listener === 'function' || listener instanceof RegExp) { + return true + } else if (listener && typeof listener === 'object') { + return isValidListener(listener.listener) + } else { + return false + } + } + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + if (!isValidListener(listener)) { + throw new TypeError('listener must be a function'); + } + + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after its first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of its properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listenersMap = this.getListenersAsObject(evt); + var listeners; + var listener; + var i; + var key; + var response; + + for (key in listenersMap) { + if (listenersMap.hasOwnProperty(key)) { + listeners = listenersMap[key].slice(0); + + for (i = 0; i < listeners.length; i++) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + // Expose the class either via AMD, CommonJS or the global object + if (typeof define === 'function' && define.amd) { + define(function () { + return EventEmitter; + }); + } + else if (typeof module === 'object' && module.exports){ + module.exports = EventEmitter; + } + else { + exports.EventEmitter = EventEmitter; + } +}(typeof window !== 'undefined' ? window : this || {})); + +},{}],16:[function(require,module,exports){ +module.exports={ + "author": "OpenVidu", + "dependencies": { + "@types/node": "12.6.8", + "@types/platform": "1.3.2", + "freeice": "2.2.2", + "hark": "1.2.3", + "platform": "1.3.5", + "uuid": "3.3.2", + "wolfy87-eventemitter": "5.2.6" + }, + "description": "OpenVidu Browser", + "devDependencies": { + "browserify": "16.3.0", + "grunt": "1.0.4", + "grunt-autoprefixer": "3.0.4", + "grunt-cli": "1.3.2", + "grunt-contrib-copy": "1.0.0", + "grunt-contrib-sass": "1.0.0", + "grunt-contrib-uglify": "4.0.1", + "grunt-contrib-watch": "1.1.0", + "grunt-string-replace": "1.3.1", + "grunt-ts": "6.0.0-beta.22", + "tsify": "4.0.1", + "tslint": "5.18.0", + "typedoc": "0.15.0", + "typescript": "3.5.3", + "uglify-js": "3.6.0" + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "openvidu-browser", + "repository": { + "type": "git", + "url": "git://github.com/OpenVidu/openvidu" + }, + "scripts": { + "browserify": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v", + "browserify-prod": "VERSION=${VERSION:-}; cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/uglify-js/bin/uglifyjs --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js", + "build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --lib dom,es5,es2015.promise,scripthost", + "docs": "./node_modules/typedoc/bin/typedoc --options ./config/typedoc.js --out ./docs ./src && rm -rf ../../openvidu.io/api/openvidu-browser/* && cp -R ./docs/. ../../openvidu.io/api/openvidu-browser", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "types": "lib/index.d.ts", + "version": "2.11.0" +} + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenVidu_1 = require("./OpenVidu/OpenVidu"); +if (window) { + window['OpenVidu'] = OpenVidu_1.OpenVidu; +} + +},{"./OpenVidu/OpenVidu":21}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Stream_1 = require("./Stream"); +var Connection = (function () { + function Connection(session, opts) { + this.session = session; + this.disposed = false; + var msg = "'Connection' created "; + if (!!opts) { + msg += "(remote) with 'connectionId' [" + opts.id + ']'; + this.options = opts; + this.connectionId = opts.id; + this.creationTime = opts.createdAt; + if (opts.metadata) { + this.data = opts.metadata; + } + if (opts.streams) { + this.initRemoteStreams(opts.streams); + } + } + else { + msg += '(local)'; + } + console.info(msg); + } + Connection.prototype.sendIceCandidate = function (candidate) { + console.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + + this.connectionId, candidate); + this.session.openvidu.sendRequest('onIceCandidate', { + endpointName: this.connectionId, + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }, function (error, response) { + if (error) { + console.error('Error sending ICE candidate: ' + + JSON.stringify(error)); + } + }); + }; + Connection.prototype.initRemoteStreams = function (options) { + var _this = this; + options.forEach(function (opts) { + var streamOptions = { + id: opts.id, + createdAt: opts.createdAt, + connection: _this, + hasAudio: opts.hasAudio, + hasVideo: opts.hasVideo, + audioActive: opts.audioActive, + videoActive: opts.videoActive, + typeOfVideo: opts.typeOfVideo, + frameRate: opts.frameRate, + videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined, + filter: !!opts.filter ? opts.filter : undefined + }; + var stream = new Stream_1.Stream(_this.session, streamOptions); + _this.addStream(stream); + }); + console.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts); + }; + Connection.prototype.addStream = function (stream) { + stream.connection = this; + this.stream = stream; + }; + Connection.prototype.removeStream = function (streamId) { + delete this.stream; + }; + Connection.prototype.dispose = function () { + if (!!this.stream) { + delete this.stream; + } + this.disposed = true; + }; + return Connection; +}()); +exports.Connection = Connection; + +},{"./Stream":24}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var Filter = (function () { + function Filter(type, options) { + this.handlers = {}; + this.type = type; + this.options = options; + } + Filter.prototype.execMethod = function (method, params) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Executing filter method to stream ' + _this.stream.streamId); + var stringParams; + if (typeof params !== 'string') { + try { + stringParams = JSON.stringify(params); + } + catch (error) { + var errorMsg = "'params' property must be a JSON formatted object"; + console.error(errorMsg); + reject(errorMsg); + } + } + else { + stringParams = params; + } + _this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) { + if (error) { + console.error('Error executing filter method for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method")); + } + else { + reject(error); + } + } + else { + console.info('Filter method successfully executed on Stream ' + _this.stream.streamId); + var oldValue = Object.assign({}, _this.stream.filter); + _this.stream.filter.lastExecMethod = { method: method, params: JSON.parse(stringParams) }; + _this.stream.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + _this.stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')]); + resolve(); + } + }); + }); + }; + Filter.prototype.addEventListener = function (eventType, handler) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + _this.handlers[eventType] = handler; + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + Filter.prototype.removeEventListener = function (eventType) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId); + _this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } + else { + reject(error); + } + } + else { + delete _this.handlers[eventType]; + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId); + resolve(); + } + }); + }); + }; + return Filter; +}()); +exports.Filter = Filter; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); +var platform = require("platform"); +var LocalRecorder = (function () { + function LocalRecorder(stream) { + this.stream = stream; + this.chunks = []; + this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; + this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; + this.state = LocalRecorderState_1.LocalRecorderState.READY; + } + LocalRecorder.prototype.record = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (typeof MediaRecorder === 'undefined') { + console.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'); + throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder')); + } + if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) { + throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before')); + } + console.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'"); + if (typeof MediaRecorder.isTypeSupported === 'function') { + var options = void 0; + if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { + options = { mimeType: 'video/webm;codecs=vp9' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) { + options = { mimeType: 'video/webm;codecs=h264' }; + } + else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { + options = { mimeType: 'video/webm;codecs=vp8' }; + } + console.log('Using mimeType ' + options.mimeType); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options); + } + else { + console.warn('isTypeSupported is not supported, using default codecs for browser'); + _this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream()); + } + _this.mediaRecorder.start(10); + } + catch (err) { + reject(err); + } + _this.mediaRecorder.ondataavailable = function (e) { + _this.chunks.push(e.data); + }; + _this.mediaRecorder.onerror = function (e) { + console.error('MediaRecorder error: ', e); + }; + _this.mediaRecorder.onstart = function () { + console.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + }; + _this.mediaRecorder.onpause = function () { + console.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onresume = function () { + console.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')'); + }; + _this.mediaRecorder.onwarning = function (e) { + console.log('MediaRecorder warning: ' + e); + }; + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + resolve(); + }); + }; + LocalRecorder.prototype.stop = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.stop()\' needs \'LocalRecord.state\' to be \'RECORDING\' or \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' before')); + } + _this.mediaRecorder.onstop = function () { + _this.onStopDefault(); + resolve(); + }; + _this.mediaRecorder.stop(); + } + catch (e) { + reject(e); + } + }); + }; + LocalRecorder.prototype.pause = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) { + reject(Error('\'LocalRecord.pause()\' needs \'LocalRecord.state\' to be \'RECORDING\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.start()\' or \'LocalRecorder.resume()\' before')); + } + _this.mediaRecorder.pause(); + _this.state = LocalRecorderState_1.LocalRecorderState.PAUSED; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.resume = function () { + var _this = this; + return new Promise(function (resolve, reject) { + try { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) { + throw (Error('\'LocalRecord.resume()\' needs \'LocalRecord.state\' to be \'PAUSED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.pause()\' before')); + } + _this.mediaRecorder.resume(); + _this.state = LocalRecorderState_1.LocalRecorderState.RECORDING; + } + catch (error) { + reject(error); + } + }); + }; + LocalRecorder.prototype.preview = function (parentElement) { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.preview()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + this.videoPreview = document.createElement('video'); + this.videoPreview.id = this.id; + this.videoPreview.autoplay = true; + if (platform.name === 'Safari') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { + var parentElementDom = document.getElementById(parentElement); + if (parentElementDom) { + this.videoPreview = parentElementDom.appendChild(this.videoPreview); + } + } + else { + this.videoPreview = parentElement.appendChild(this.videoPreview); + } + this.videoPreview.src = this.videoPreviewSrc; + return this.videoPreview; + }; + LocalRecorder.prototype.clean = function () { + var _this = this; + var f = function () { + delete _this.blob; + _this.chunks = []; + delete _this.mediaRecorder; + _this.state = LocalRecorderState_1.LocalRecorderState.READY; + }; + if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) { + this.stop().then(function () { return f(); }).catch(function () { return f(); }); + } + else { + f(); + } + }; + LocalRecorder.prototype.download = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('\'LocalRecord.download()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var a = document.createElement('a'); + a.style.display = 'none'; + document.body.appendChild(a); + var url = window.URL.createObjectURL(this.blob); + a.href = url; + a.download = this.id + '.webm'; + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + } + }; + LocalRecorder.prototype.getBlob = function () { + if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + throw (Error('Call \'LocalRecord.stop()\' before getting Blob file')); + } + else { + return this.blob; + } + }; + LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsBinary()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_1 = new XMLHttpRequest(); + http_1.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_1.setRequestHeader(key, headers[key]); + } + } + http_1.onreadystatechange = function () { + if (http_1.readyState === 4) { + if (http_1.status.toString().charAt(0) === '2') { + resolve(http_1.responseText); + } + else { + reject(http_1.status); + } + } + }; + http_1.send(_this.blob); + } + }); + }; + LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) { + reject(Error('\'LocalRecord.uploadAsMultipartfile()\' needs \'LocalRecord.state\' to be \'FINISHED\' (current value: \'' + _this.state + '\'). Call \'LocalRecorder.stop()\' before')); + } + else { + var http_2 = new XMLHttpRequest(); + http_2.open('POST', endpoint, true); + if (typeof headers === 'object') { + for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) { + var key = _a[_i]; + http_2.setRequestHeader(key, headers[key]); + } + } + var sendable = new FormData(); + sendable.append('file', _this.blob, _this.id + '.webm'); + http_2.onreadystatechange = function () { + if (http_2.readyState === 4) { + if (http_2.status.toString().charAt(0) === '2') { + resolve(http_2.responseText); + } + else { + reject(http_2.status); + } + } + }; + http_2.send(sendable); + } + }); + }; + LocalRecorder.prototype.onStopDefault = function () { + console.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')'); + this.blob = new Blob(this.chunks, { type: 'video/webm' }); + this.chunks = []; + this.videoPreviewSrc = window.URL.createObjectURL(this.blob); + this.state = LocalRecorderState_1.LocalRecorderState.FINISHED; + }; + return LocalRecorder; +}()); +exports.LocalRecorder = LocalRecorder; + +},{"../OpenViduInternal/Enums/LocalRecorderState":27,"platform":8}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorder_1 = require("./LocalRecorder"); +var Publisher_1 = require("./Publisher"); +var Session_1 = require("./Session"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto"); +var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); +var EventEmitter = require("wolfy87-eventemitter"); +var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); +var platform = require("platform"); +platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1; +platform['isIonicAndroid'] = platform.os.family === 'Android' && platform.name == "Android Browser"; +var packageJson = require('../../package.json'); +var OpenVidu = (function () { + function OpenVidu() { + var _this = this; + this.publishers = []; + this.secret = ''; + this.recorder = false; + this.advancedConfiguration = {}; + this.webrtcStatsInterval = 0; + this.ee = new EventEmitter(); + this.libraryVersion = packageJson.version; + console.info("'OpenVidu' initialized"); + console.info("openvidu-browser version: " + this.libraryVersion); + if (platform.os.family === 'iOS' || platform.os.family === 'Android') { + window.addEventListener('orientationchange', function () { + _this.publishers.forEach(function (publisher) { + if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { + var attempts_1 = 0; + var oldWidth_1 = publisher.stream.videoDimensions.width; + var oldHeight_1 = publisher.stream.videoDimensions.height; + var getNewVideoDimensions_1 = function () { + return new Promise(function (resolve, reject) { + if (platform['isIonicIos']) { + resolve({ + newWidth: publisher.stream.streamManager.videos[0].video.videoWidth, + newHeight: publisher.stream.streamManager.videos[0].video.videoHeight + }); + } + else { + var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); + var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth); + var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight); + resolve({ newWidth: newWidth, newHeight: newHeight }); + } + }); + }; + var repeatUntilChange_1 = setInterval(function () { + getNewVideoDimensions_1().then(function (newDimensions) { + sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight); + }); + }, 75); + var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { + attempts_1++; + if (attempts_1 > 10) { + clearTimeout(repeatUntilChange_1); + } + if (newWidth !== oldWidth || newHeight !== oldHeight) { + publisher.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.sendRequest('streamPropertyChanged', { + streamId: publisher.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(publisher.stream.videoDimensions), + reason: 'deviceRotated' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + publisher.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, 'deviceRotated')]); + } + }); + clearTimeout(repeatUntilChange_1); + } + }; + } + }); + }); + } + } + OpenVidu.prototype.initSession = function () { + this.session = new Session_1.Session(this); + return this.session; + }; + OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) { + var properties; + if (!!param2 && (typeof param2 !== 'function')) { + properties = param2; + properties = { + audioSource: (typeof properties.audioSource !== 'undefined') ? properties.audioSource : undefined, + frameRate: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.frameRate !== 'undefined') ? properties.frameRate : undefined), + insertMode: (typeof properties.insertMode !== 'undefined') ? ((typeof properties.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[properties.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: (typeof properties.mirror !== 'undefined') ? properties.mirror : true, + publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true, + publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true, + resolution: (typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'), + videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined, + filter: properties.filter + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + mirror: true, + publishAudio: true, + publishVideo: true, + resolution: '640x480' + }; + } + var publisher = new Publisher_1.Publisher(targetElement, properties, this); + var completionHandler; + if (!!param2 && (typeof param2 === 'function')) { + completionHandler = param2; + } + else if (!!param3) { + completionHandler = param3; + } + publisher.initialize() + .then(function () { + if (completionHandler !== undefined) { + completionHandler(undefined); + } + publisher.emitEvent('accessAllowed', []); + }).catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + publisher.emitEvent('accessDenied', [error]); + }); + this.publishers.push(publisher); + return publisher; + }; + OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var publisher; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(publisher); + } + }; + if (!!properties) { + publisher = _this.initPublisher(targetElement, properties, callback); + } + else { + publisher = _this.initPublisher(targetElement, callback); + } + }); + }; + OpenVidu.prototype.initLocalRecorder = function (stream) { + return new LocalRecorder_1.LocalRecorder(stream); + }; + OpenVidu.prototype.checkSystemRequirements = function () { + var browser = platform.name; + var family = platform.os.family; + var userAgent = !!platform.ua ? platform.ua : navigator.userAgent; + if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) { + return 0; + } + if ((browser !== 'Safari') && + (browser !== 'Chrome') && (browser !== 'Chrome Mobile') && + (browser !== 'Firefox') && (browser !== 'Firefox Mobile') && + (browser !== 'Opera') && (browser !== 'Opera Mobile') && + (browser !== 'Android Browser') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.checkScreenSharingCapabilities = function () { + var browser = platform.name; + var family = platform.os.family; + if (family === 'iOS' || family === 'Android') { + return 0; + } + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron')) { + return 0; + } + else { + return 1; + } + }; + OpenVidu.prototype.getDevices = function () { + return new Promise(function (resolve, reject) { + navigator.mediaDevices.enumerateDevices().then(function (deviceInfos) { + var devices = []; + if (platform['isIonicAndroid'] && cordova.plugins && cordova.plugins.EnumerateDevicesPlugin) { + cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) { + var pluginAudioDevices = []; + var videoDevices = []; + var audioDevices = []; + pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; }); + audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; }); + videoDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + if (index === 0) { + label = "Front Camera"; + } + else if (index === 1) { + label = "Back Camera"; + } + else { + label = "Unknown Camera"; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + audioDevices.forEach(function (deviceInfo, index) { + if (!deviceInfo.label) { + var label = ""; + switch (index) { + case 0: + label = 'Default'; + break; + case 1: + var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0]; + label = defaultMatch ? defaultMatch.label : 'Built-in Microphone'; + break; + case 2: + var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0]; + if (wiredMatch) { + label = wiredMatch.label; + } + else { + label = 'Headset earpiece'; + } + break; + case 3: + var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0]; + label = wirelessMatch ? wirelessMatch.label : 'Wireless'; + break; + default: + label = "Unknown Microphone"; + break; + } + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: label + }); + } + else { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + }); + } + else { + deviceInfos.forEach(function (deviceInfo) { + if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { + devices.push({ + kind: deviceInfo.kind, + deviceId: deviceInfo.deviceId, + label: deviceInfo.label + }); + } + }); + resolve(devices); + } + }).catch(function (error) { + console.error('Error getting devices', error); + reject(error); + }); + }); + }; + OpenVidu.prototype.getUserMedia = function (options) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.generateMediaConstraints(options) + .then(function (constraints) { + navigator.mediaDevices.getUserMedia(constraints) + .then(function (mediaStream) { + resolve(mediaStream); + }) + .catch(function (error) { + var errorName; + var errorMessage = error.toString(); + if (!(options.videoSource === 'screen')) { + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED; + } + reject(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + OpenVidu.prototype.enableProdMode = function () { + console.log = function () { }; + console.debug = function () { }; + console.info = function () { }; + console.warn = function () { }; + }; + OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { + this.advancedConfiguration = configuration; + }; + OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) { + var _this = this; + return new Promise(function (resolve, reject) { + var audio, video; + if (publisherProperties.audioSource === null || publisherProperties.audioSource === false) { + audio = false; + } + else if (publisherProperties.audioSource === undefined) { + audio = true; + } + else { + audio = publisherProperties.audioSource; + } + if (publisherProperties.videoSource === null || publisherProperties.videoSource === false) { + video = false; + } + else { + video = { + height: { + ideal: 480 + }, + width: { + ideal: 640 + } + }; + } + var mediaConstraints = { + audio: audio, + video: video + }; + if (typeof mediaConstraints.audio === 'string') { + mediaConstraints.audio = { deviceId: { exact: mediaConstraints.audio } }; + } + if (mediaConstraints.video) { + if (!!publisherProperties.resolution) { + var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x'); + var width = Number(widthAndHeight[0]); + var height = Number(widthAndHeight[1]); + mediaConstraints.video.width.ideal = width; + mediaConstraints.video.height.ideal = height; + } + if (!!publisherProperties.frameRate) { + mediaConstraints.video.frameRate = { ideal: publisherProperties.frameRate }; + } + if (!!publisherProperties.videoSource && typeof publisherProperties.videoSource === 'string') { + if (publisherProperties.videoSource === 'screen' || + (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window') || + (platform.name === 'Electron' && publisherProperties.videoSource.startsWith('screen:'))) { + if (!_this.checkScreenSharingCapabilities()) { + var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera or Electron. Detected client: ' + platform.name); + console.error(error); + reject(error); + } + else { + if (platform.name === 'Electron') { + var prefix = "screen:"; + var videoSourceString = publisherProperties.videoSource; + var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length); + mediaConstraints['video'] = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: electronScreenId + } + }; + resolve(mediaConstraints); + } + else { + if (!!_this.advancedConfiguration.screenShareChromeExtension && !(platform.name.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) { + screenSharing.getScreenConstraints(function (error, screenConstraints) { + if (!!error || !!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen') { + if (error === 'permission-denied' || error === 'PermissionDeniedError') { + var error_1 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_1); + reject(error_1); + } + else { + var extensionId = _this.advancedConfiguration.screenShareChromeExtension.split('/').pop().trim(); + screenSharing.getChromeExtensionStatus(extensionId, function (status) { + if (status === 'installed-disabled') { + var error_2 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_2); + reject(error_2); + } + if (status === 'not-installed') { + var error_3 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension); + console.error(error_3); + reject(error_3); + } + }); + } + } + else { + mediaConstraints.video = screenConstraints; + resolve(mediaConstraints); + } + }); + } + else { + if (navigator.mediaDevices['getDisplayMedia']) { + resolve(mediaConstraints); + } + else { + var firefoxString = platform.name.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined; + screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) { + if (!!error) { + if (error === 'not-installed') { + var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension ? _this.advancedConfiguration.screenShareChromeExtension : + 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold'; + var error_4 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl); + console.error(error_4); + reject(error_4); + } + else if (error === 'installed-disabled') { + var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension'); + console.error(error_5); + reject(error_5); + } + else if (error === 'permission-denied') { + var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error_6); + reject(error_6); + } + } + else { + mediaConstraints.video = screenConstraints.video; + resolve(mediaConstraints); + } + }); + } + } + publisherProperties.videoSource = 'screen'; + } + } + } + else { + mediaConstraints.video['deviceId'] = { exact: publisherProperties.videoSource }; + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + } + else { + resolve(mediaConstraints); + } + }); + }; + OpenVidu.prototype.startWs = function (onConnectSucces) { + var config = { + heartbeat: 5000, + sendCloseMessage: false, + ws: { + uri: this.wsUri, + useSockJS: false, + onconnected: onConnectSucces, + ondisconnect: this.disconnectCallback.bind(this), + onreconnecting: this.reconnectingCallback.bind(this), + onreconnected: this.reconnectedCallback.bind(this) + }, + rpc: { + requestTimeout: 10000, + participantJoined: this.session.onParticipantJoined.bind(this.session), + participantPublished: this.session.onParticipantPublished.bind(this.session), + participantUnpublished: this.session.onParticipantUnpublished.bind(this.session), + participantLeft: this.session.onParticipantLeft.bind(this.session), + participantEvicted: this.session.onParticipantEvicted.bind(this.session), + recordingStarted: this.session.onRecordingStarted.bind(this.session), + recordingStopped: this.session.onRecordingStopped.bind(this.session), + sendMessage: this.session.onNewMessage.bind(this.session), + streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), + iceCandidate: this.session.recvIceCandidate.bind(this.session), + mediaError: this.session.onMediaError.bind(this.session) + } + }; + this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config); + }; + OpenVidu.prototype.closeWs = function () { + this.jsonRpcClient.close(4102, "Connection closed by client"); + }; + OpenVidu.prototype.sendRequest = function (method, params, callback) { + if (params && params instanceof Function) { + callback = params; + params = {}; + } + console.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}'); + this.jsonRpcClient.send(method, params, callback); + }; + OpenVidu.prototype.getWsUri = function () { + return this.wsUri; + }; + OpenVidu.prototype.getSecret = function () { + return this.secret; + }; + OpenVidu.prototype.getRecorder = function () { + return this.recorder; + }; + OpenVidu.prototype.disconnectCallback = function () { + console.warn('Websocket connection lost'); + if (this.isRoomAvailable()) { + this.session.onLostConnection('networkDisconnect'); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectingCallback = function () { + console.warn('Websocket connection lost (reconnecting)'); + if (!this.isRoomAvailable()) { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.reconnectedCallback = function () { + var _this = this; + console.warn('Websocket reconnected'); + if (this.isRoomAvailable()) { + this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, function (error, response) { + if (!!error) { + console.error(error); + _this.session.onLostConnection("networkDisconnect"); + _this.jsonRpcClient.close(4101, "Reconnection fault"); + } + else { + _this.jsonRpcClient.resetPing(); + _this.session.onRecoveredConnection(); + } + }); + } + else { + alert('Connection error. Please reload page.'); + } + }; + OpenVidu.prototype.isRoomAvailable = function () { + if (this.session !== undefined && this.session instanceof Session_1.Session) { + return true; + } + else { + console.warn('Session instance not found'); + return false; + } + }; + return OpenVidu; +}()); +exports.OpenVidu = OpenVidu; + +},{"../../package.json":16,"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":46,"../OpenViduInternal/ScreenSharing/Screen-Capturing":51,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":50,"./LocalRecorder":20,"./Publisher":22,"./Session":23,"platform":8,"wolfy87-eventemitter":15}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Session_1 = require("./Session"); +var Stream_1 = require("./Stream"); +var StreamManager_1 = require("./StreamManager"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var platform = require("platform"); +var Publisher = (function (_super) { + __extends(Publisher, _super); + function Publisher(targEl, properties, openvidu) { + var _this = _super.call(this, new Stream_1.Stream((!!openvidu.session) ? openvidu.session : new Session_1.Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl) || this; + _this.accessAllowed = false; + _this.isSubscribedToRemote = false; + _this.accessDenied = false; + _this.properties = properties; + _this.openvidu = openvidu; + _this.stream.ee.on('local-stream-destroyed', function (reason) { + _this.stream.isLocalStreamPublished = false; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason); + _this.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + }); + return _this; + } + Publisher.prototype.publishAudio = function (value) { + var _this = this; + if (this.stream.audioActive !== value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'audioActive', + newValue: value, + reason: 'publishAudio' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); + } + }); + } + this.stream.audioActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); + } + }; + Publisher.prototype.publishVideo = function (value) { + var _this = this; + if (this.stream.videoActive !== value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + if (!!this.session && !!this.stream.streamId) { + this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: this.stream.streamId, + property: 'videoActive', + newValue: value, + reason: 'publishVideo' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); + } + }); + } + this.stream.videoActive = value; + console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); + } + }; + Publisher.prototype.subscribeToRemote = function (value) { + value = (value !== undefined) ? value : true; + this.isSubscribedToRemote = value; + this.stream.subscribeToMyRemote(value); + }; + Publisher.prototype.on = function (type, handler) { + var _this = this; + _super.prototype.on.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.on('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.once = function (type, handler) { + var _this = this; + _super.prototype.once.call(this, type, handler); + if (type === 'streamCreated') { + if (!!this.stream && this.stream.isLocalStreamPublished) { + this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]); + } + else { + this.stream.ee.once('stream-created-by-publisher', function () { + _this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]); + }); + } + } + if (type === 'remoteVideoPlaying') { + if (this.stream.displayMyRemote() && this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]); + } + } + if (type === 'accessAllowed') { + if (this.accessAllowed) { + this.emitEvent('accessAllowed', []); + } + } + if (type === 'accessDenied') { + if (this.accessDenied) { + this.emitEvent('accessDenied', []); + } + } + return this; + }; + Publisher.prototype.initialize = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var constraints = {}; + var constraintsAux = {}; + var timeForDialogEvent = 1250; + var startTime; + var errorCallback = function (openViduError) { + _this.accessDenied = true; + _this.accessAllowed = false; + reject(openViduError); + }; + var successCallback = function (mediaStream) { + _this.accessAllowed = true; + _this.accessDenied = false; + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getAudioTracks()[0]); + mediaStream.addTrack(_this.properties.audioSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.removeTrack(mediaStream.getVideoTracks()[0]); + mediaStream.addTrack(_this.properties.videoSource); + } + if (!!mediaStream.getAudioTracks()[0]) { + var enabled = (_this.stream.audioActive !== undefined && _this.stream.audioActive !== null) ? _this.stream.audioActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio; + mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!mediaStream.getVideoTracks()[0]) { + var enabled = (_this.stream.videoActive !== undefined && _this.stream.videoActive !== null) ? _this.stream.videoActive : !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo; + mediaStream.getVideoTracks()[0].enabled = enabled; + } + _this.videoReference = document.createElement('video'); + if (platform.name === 'Safari') { + _this.videoReference.setAttribute('playsinline', 'true'); + } + _this.stream.setMediaStream(mediaStream); + if (!!_this.firstVideoElement) { + _this.createVideoElement(_this.firstVideoElement.targetElement, _this.properties.insertMode); + } + _this.videoReference.srcObject = mediaStream; + if (!_this.stream.displayMyRemote()) { + _this.stream.updateMediaStreamInVideos(); + } + delete _this.firstVideoElement; + if (_this.stream.isSendVideo()) { + if (!_this.stream.isSendScreen()) { + if (platform['isIonicIos'] || platform.name === 'Safari') { + _this.videoReference.style.display = 'none'; + document.body.appendChild(_this.videoReference); + var videoDimensionsSet_1 = function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + document.body.removeChild(_this.videoReference); + }; + var interval_1; + _this.videoReference.addEventListener('loadedmetadata', function () { + if (_this.videoReference.videoWidth === 0) { + interval_1 = setInterval(function () { + if (_this.videoReference.videoWidth !== 0) { + clearInterval(interval_1); + videoDimensionsSet_1(); + } + }, 40); + } + else { + videoDimensionsSet_1(); + } + }); + } + else { + var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height; + if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) { + _this.stream.videoDimensions = { + width: height || 0, + height: width || 0 + }; + } + else { + _this.stream.videoDimensions = { + width: width || 0, + height: height || 0 + }; + } + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + } + else { + _this.videoReference.addEventListener('loadedmetadata', function () { + _this.stream.videoDimensions = { + width: _this.videoReference.videoWidth, + height: _this.videoReference.videoHeight + }; + _this.screenShareResizeInterval = setInterval(function () { + var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); + var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width; + var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height; + if (_this.stream.isLocalStreamPublished && + (newWidth !== _this.stream.videoDimensions.width || + newHeight !== _this.stream.videoDimensions.height)) { + var oldValue_1 = { width: _this.stream.videoDimensions.width, height: _this.stream.videoDimensions.height }; + _this.stream.videoDimensions = { + width: newWidth || 0, + height: newHeight || 0 + }; + _this.session.openvidu.sendRequest('streamPropertyChanged', { + streamId: _this.stream.streamId, + property: 'videoDimensions', + newValue: JSON.stringify(_this.stream.videoDimensions), + reason: 'screenResized' + }, function (error, response) { + if (error) { + console.error("Error sending 'streamPropertyChanged' event", error); + } + else { + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoDimensions', _this.stream.videoDimensions, oldValue_1, 'screenResized')]); + } + }); + } + }, 500); + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + }); + } + } + else { + _this.stream.isLocalStreamReadyToPublish = true; + _this.stream.ee.emitEvent('stream-ready-to-publish', []); + } + resolve(); + }; + var getMediaSuccess = function (mediaStream, definedAudioConstraint) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (_this.stream.isSendScreen() && _this.stream.isSendAudio()) { + constraintsAux.audio = definedAudioConstraint; + constraintsAux.video = false; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (audioOnlyStream) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]); + successCallback(mediaStream); + }) + .catch(function (error) { + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'notallowederror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }); + } + else { + successCallback(mediaStream); + } + }; + var getMediaError = function (error) { + console.error(error); + _this.clearPermissionDialogTimer(startTime, timeForDialogEvent); + if (error.name === 'Error') { + error.name = error.constructor.name; + } + var errorName, errorMessage; + switch (error.name.toLowerCase()) { + case 'notfounderror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'notallowederror': + errorName = _this.stream.isSendScreen() ? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED : OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + case 'overconstrainederror': + navigator.mediaDevices.getUserMedia({ + audio: false, + video: constraints.video + }) + .then(function (mediaStream) { + mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND; + errorMessage = "Audio input device with deviceId '" + constraints.audio.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }).catch(function (e) { + if (error.constraint.toLowerCase() === 'deviceid') { + errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND; + errorMessage = "Video input device with deviceId '" + constraints.video.deviceId.exact + "' not found"; + } + else { + errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR; + errorMessage = "Video input device doesn't support the value passed for constraint '" + error.constraint + "'"; + } + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + }); + break; + case 'aborterror': + case 'notreadableerror': + errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + default: + errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR; + errorMessage = error.toString(); + errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage)); + break; + } + }; + if ((typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && !_this.properties.audioSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack && !_this.properties.videoSource) + || (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack && _this.properties.audioSource instanceof MediaStreamTrack)) { + var mediaStream = new MediaStream(); + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.videoSource); + } + if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) { + mediaStream.addTrack(_this.properties.audioSource); + } + successCallback(mediaStream); + return; + } + _this.openvidu.generateMediaConstraints(_this.properties) + .then(function (myConstraints) { + constraints = myConstraints; + var outboundStreamOptions = { + mediaConstraints: constraints, + publisherProperties: _this.properties + }; + _this.stream.setOutboundStreamOptions(outboundStreamOptions); + if (_this.stream.isSendVideo() || _this.stream.isSendAudio()) { + var definedAudioConstraint_1 = ((constraints.audio === undefined) ? true : constraints.audio); + constraintsAux.audio = _this.stream.isSendScreen() ? false : definedAudioConstraint_1; + constraintsAux.video = constraints.video; + startTime = Date.now(); + _this.setPermissionDialogTimer(timeForDialogEvent); + if (_this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') { + navigator.mediaDevices['getDisplayMedia']({ video: true }) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + else { + navigator.mediaDevices.getUserMedia(constraintsAux) + .then(function (mediaStream) { + getMediaSuccess(mediaStream, definedAudioConstraint_1); + }) + .catch(function (error) { + getMediaError(error); + }); + } + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time when calling 'OpenVidu.initPublisher'")); + } + }) + .catch(function (error) { + errorCallback(error); + }); + }); + }; + Publisher.prototype.reestablishStreamPlayingEvent = function () { + if (this.ee.getListeners('streamPlaying').length > 0) { + this.addPlayEventToFirstVideo(); + } + }; + Publisher.prototype.setPermissionDialogTimer = function (waitTime) { + var _this = this; + this.permissionDialogTimeout = setTimeout(function () { + _this.emitEvent('accessDialogOpened', []); + }, waitTime); + }; + Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) { + clearTimeout(this.permissionDialogTimeout); + if ((Date.now() - startTime) > waitTime) { + this.emitEvent('accessDialogClosed', []); + } + }; + return Publisher; +}(StreamManager_1.StreamManager)); +exports.Publisher = Publisher; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/Events/VideoElementEvent":40,"./Session":23,"./Stream":24,"./StreamManager":25,"platform":8}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Connection_1 = require("./Connection"); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent"); +var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent"); +var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent"); +var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent"); +var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent"); +var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var Session = (function () { + function Session(openvidu) { + this.streamManagers = []; + this.remoteStreamsCreated = {}; + this.isFirstIonicIosSubscriber = true; + this.countDownForIonicIosSubscribersActive = true; + this.remoteConnections = {}; + this.speakingEventsEnabled = false; + this.ee = new EventEmitter(); + this.openvidu = openvidu; + } + Session.prototype.connect = function (token, metadata) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.processToken(token); + if (_this.openvidu.checkSystemRequirements()) { + _this.options = { + sessionId: _this.sessionId, + participantId: token, + metadata: !!metadata ? _this.stringClientMetadata(metadata) : '' + }; + _this.connectAux(token).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os.family + ' is not supported in OpenVidu')); + } + }); + }; + Session.prototype.disconnect = function () { + this.leave(false, 'disconnect'); + }; + Session.prototype.subscribe = function (stream, targetElement, param3, param4) { + var properties = {}; + if (!!param3 && typeof param3 !== 'function') { + properties = { + insertMode: (typeof param3.insertMode !== 'undefined') ? ((typeof param3.insertMode === 'string') ? VideoInsertMode_1.VideoInsertMode[param3.insertMode] : properties.insertMode) : VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: (typeof param3.subscribeToAudio !== 'undefined') ? param3.subscribeToAudio : true, + subscribeToVideo: (typeof param3.subscribeToVideo !== 'undefined') ? param3.subscribeToVideo : true + }; + } + else { + properties = { + insertMode: VideoInsertMode_1.VideoInsertMode.APPEND, + subscribeToAudio: true, + subscribeToVideo: true + }; + } + var completionHandler; + if (!!param3 && (typeof param3 === 'function')) { + completionHandler = param3; + } + else if (!!param4) { + completionHandler = param4; + } + console.info('Subscribing to ' + stream.connection.connectionId); + stream.subscribe() + .then(function () { + console.info('Subscribed correctly to ' + stream.connection.connectionId); + if (completionHandler !== undefined) { + completionHandler(undefined); + } + }) + .catch(function (error) { + if (completionHandler !== undefined) { + completionHandler(error); + } + }); + var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties); + if (!!subscriber.targetElement) { + stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode); + } + return subscriber; + }; + Session.prototype.subscribeAsync = function (stream, targetElement, properties) { + var _this = this; + return new Promise(function (resolve, reject) { + var subscriber; + var callback = function (error) { + if (!!error) { + reject(error); + } + else { + resolve(subscriber); + } + }; + if (!!properties) { + subscriber = _this.subscribe(stream, targetElement, properties, callback); + } + else { + subscriber = _this.subscribe(stream, targetElement, callback); + } + }); + }; + Session.prototype.unsubscribe = function (subscriber) { + var connectionId = subscriber.stream.connection.connectionId; + console.info('Unsubscribing from ' + connectionId); + this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) { + if (error) { + console.error('Error unsubscribing from ' + connectionId, error); + } + else { + console.info('Unsubscribed correctly from ' + connectionId); + } + subscriber.stream.disposeWebRtcPeer(); + subscriber.stream.disposeMediaStream(); + }); + subscriber.stream.streamManager.removeAllVideos(); + }; + Session.prototype.publish = function (publisher) { + var _this = this; + return new Promise(function (resolve, reject) { + publisher.session = _this; + publisher.stream.session = _this; + if (!publisher.stream.publishedOnce) { + _this.connection.addStream(publisher.stream); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + publisher.initialize() + .then(function () { + _this.connection.addStream(publisher.stream); + publisher.reestablishStreamPlayingEvent(); + publisher.stream.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + Session.prototype.unpublish = function (publisher) { + var stream = publisher.stream; + if (!stream.connection) { + console.error('The associated Connection object of this Publisher is null', stream); + return; + } + else if (stream.connection !== this.connection) { + console.error('The associated Connection object of this Publisher is not your local Connection.' + + "Only moderators can force unpublish on remote Streams via 'forceUnpublish' method", stream); + return; + } + else { + console.info('Unpublishing local media (' + stream.connection.connectionId + ')'); + this.openvidu.sendRequest('unpublishVideo', function (error, response) { + if (error) { + console.error(error); + } + else { + console.info('Media unpublished correctly'); + } + }); + stream.disposeWebRtcPeer(); + delete stream.connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish'); + publisher.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + } + }; + Session.prototype.forceDisconnect = function (connection) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing disconnect for connection ' + connection.connectionId); + _this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) { + if (error) { + console.error('Error forcing disconnect for Connection ' + connection.connectionId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection")); + } + else { + reject(error); + } + } + else { + console.info('Forcing disconnect correctly for Connection ' + connection.connectionId); + resolve(); + } + }); + }); + }; + Session.prototype.forceUnpublish = function (stream) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Forcing unpublish for stream ' + stream.streamId); + _this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) { + if (error) { + console.error('Error forcing unpublish for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing")); + } + else { + reject(error); + } + } + else { + console.info('Forcing unpublish correctly for Stream ' + stream.streamId); + resolve(); + } + }); + }); + }; + Session.prototype.signal = function (signal) { + var _this = this; + return new Promise(function (resolve, reject) { + var signalMessage = {}; + if (signal.to && signal.to.length > 0) { + var connectionIds_1 = []; + signal.to.forEach(function (connection) { + connectionIds_1.push(connection.connectionId); + }); + signalMessage['to'] = connectionIds_1; + } + else { + signalMessage['to'] = []; + } + signalMessage['data'] = signal.data ? signal.data : ''; + var typeAux = signal.type ? signal.type : 'signal'; + if (!!typeAux) { + if (typeAux.substring(0, 7) !== 'signal:') { + typeAux = 'signal:' + typeAux; + } + } + signalMessage['type'] = typeAux; + _this.openvidu.sendRequest('sendMessage', { + message: JSON.stringify(signalMessage) + }, function (error, response) { + if (!!error) { + reject(error); + } + else { + resolve(); + } + }); + }); + }; + Session.prototype.on = function (type, handler) { + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by 'Session'", event); + } + else { + console.info("Event '" + type + "' triggered by 'Session'"); + } + handler(event); + }); + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = true; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str && str.hasAudio) { + str.enableOnceSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'publisherStartSpeaking' || type === 'publisherStopSpeaking') { + this.speakingEventsEnabled = false; + for (var connectionId in this.remoteConnections) { + var str = this.remoteConnections[connectionId].stream; + if (!!str) { + str.disableSpeakingEvents(); + } + } + } + return this; + }; + Session.prototype.onParticipantJoined = function (response) { + var _this = this; + this.getConnection(response.id, '') + .then(function (connection) { + console.warn('Connection ' + response.id + ' already exists in connections list'); + }) + .catch(function (openViduError) { + var connection = new Connection_1.Connection(_this, response); + _this.remoteConnections[response.id] = connection; + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + }; + Session.prototype.onParticipantLeft = function (msg) { + var _this = this; + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + if (!!connection.stream) { + var stream = connection.stream; + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + delete _this.remoteStreamsCreated[stream.streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + } + delete _this.remoteConnections[connection.connectionId]; + _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onParticipantPublished = function (response) { + var _this = this; + var afterConnectionFound = function (connection) { + _this.remoteConnections[connection.connectionId] = connection; + if (!_this.remoteStreamsCreated[connection.stream.streamId]) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]); + } + _this.remoteStreamsCreated[connection.stream.streamId] = true; + }; + var connection; + this.getRemoteConnection(response.id, "Remote connection '" + response.id + "' unknown when 'onParticipantPublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (con) { + connection = con; + response.metadata = con.data; + connection.options = response; + connection.initRemoteStreams(response.streams); + afterConnectionFound(connection); + }) + .catch(function (openViduError) { + connection = new Connection_1.Connection(_this, response); + afterConnectionFound(connection); + }); + }; + Session.prototype.onParticipantUnpublished = function (msg) { + var _this = this; + if (msg.connectionId === this.connection.connectionId) { + this.stopPublisherStream(msg.reason); + } + else { + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, msg.reason); + _this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); + var streamId = connection.stream.streamId; + delete _this.remoteStreamsCreated[streamId]; + if (Object.keys(_this.remoteStreamsCreated).length === 0) { + _this.isFirstIonicIosSubscriber = true; + _this.countDownForIonicIosSubscribersActive = true; + } + connection.removeStream(streamId); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.onParticipantEvicted = function (msg) { + if (msg.connectionId === this.connection.connectionId) { + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } + }; + Session.prototype.onNewMessage = function (msg) { + var _this = this; + console.info('New signal: ' + JSON.stringify(msg)); + this.getConnection(msg.from, "Connection '" + msg.from + "' unknow when 'onNewMessage'. Existing remote connections: " + + JSON.stringify(Object.keys(this.remoteConnections)) + '. Existing local connection: ' + this.connection.connectionId) + .then(function (connection) { + _this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + if (msg.type !== 'signal') { + _this.ee.emitEvent(msg.type, [new SignalEvent_1.SignalEvent(_this, msg.type, msg.data, connection)]); + } + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onStreamPropertyChanged = function (msg) { + var _this = this; + var callback = function (connection) { + if (!!connection.stream && connection.stream.streamId === msg.streamId) { + var stream = connection.stream; + var oldValue = void 0; + switch (msg.property) { + case 'audioActive': + oldValue = stream.audioActive; + msg.newValue = msg.newValue === 'true'; + stream.audioActive = msg.newValue; + break; + case 'videoActive': + oldValue = stream.videoActive; + msg.newValue = msg.newValue === 'true'; + stream.videoActive = msg.newValue; + break; + case 'videoDimensions': + oldValue = stream.videoDimensions; + msg.newValue = JSON.parse(JSON.parse(msg.newValue)); + stream.videoDimensions = msg.newValue; + break; + case 'filter': + oldValue = stream.filter; + msg.newValue = (Object.keys(msg.newValue).length > 0) ? msg.newValue : undefined; + if (msg.newValue !== undefined) { + stream.filter = new Filter_1.Filter(msg.newValue.type, msg.newValue.options); + stream.filter.stream = stream; + if (msg.newValue.lastExecMethod) { + stream.filter.lastExecMethod = msg.newValue.lastExecMethod; + } + } + else { + delete stream.filter; + } + msg.newValue = stream.filter; + break; + } + _this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + if (!!stream.streamManager) { + stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, msg.property, msg.newValue, oldValue, msg.reason)]); + } + } + else { + console.error("No stream with streamId '" + msg.streamId + "' found for connection '" + msg.connectionId + "' on 'streamPropertyChanged' event"); + } + }; + if (msg.connectionId === this.connection.connectionId) { + callback(this.connection); + } + else { + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onStreamPropertyChanged'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + .then(function (connection) { + callback(connection); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + } + }; + Session.prototype.recvIceCandidate = function (msg) { + var candidate = { + candidate: msg.candidate, + component: msg.component, + foundation: msg.foundation, + ip: msg.ip, + port: msg.port, + priority: msg.priority, + protocol: msg.protocol, + relatedAddress: msg.relatedAddress, + relatedPort: msg.relatedPort, + sdpMid: msg.sdpMid, + sdpMLineIndex: msg.sdpMLineIndex, + tcpType: msg.tcpType, + usernameFragment: msg.usernameFragment, + type: msg.type, + toJSON: function () { + return { candidate: msg.candidate }; + } + }; + this.getConnection(msg.senderConnectionId, 'Connection not found for connectionId ' + msg.senderConnectionId + ' owning endpoint ' + msg.endpointName + '. Ice candidate will be ignored: ' + candidate) + .then(function (connection) { + var stream = connection.stream; + stream.getWebRtcPeer().addIceCandidate(candidate).catch(function (error) { + console.error('Error adding candidate for ' + stream.streamId + + ' stream of endpoint ' + msg.endpointName + ': ' + error); + }); + }) + .catch(function (openViduError) { + console.error(openViduError); + }); + }; + Session.prototype.onSessionClosed = function (msg) { + console.info('Session closed: ' + JSON.stringify(msg)); + var s = msg.sessionId; + if (s !== undefined) { + this.ee.emitEvent('session-closed', [{ + session: s + }]); + } + else { + console.warn('Session undefined on session closed', msg); + } + }; + Session.prototype.onLostConnection = function (reason) { + console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect'); + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, reason); + } + }; + Session.prototype.onRecoveredConnection = function () { + console.warn('Recovered connection in Session ' + this.sessionId); + }; + Session.prototype.onMediaError = function (params) { + console.error('Media error: ' + JSON.stringify(params)); + var err = params.error; + if (err) { + this.ee.emitEvent('error-media', [{ + error: err + }]); + } + else { + console.warn('Received undefined media error. Params:', params); + } + }; + Session.prototype.onRecordingStarted = function (response) { + this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', response.id, response.name)]); + }; + Session.prototype.onRecordingStopped = function (response) { + this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', response.id, response.name, response.reason)]); + }; + Session.prototype.onFilterEventDispatched = function (response) { + var connectionId = response.connectionId; + var streamId = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(function (connection) { + console.info('Filter event dispatched'); + var stream = connection.stream; + stream.filter.handlers[response.eventType](new FilterEvent_1.FilterEvent(stream.filter, response.eventType, response.data)); + }); + }; + Session.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + Session.prototype.leave = function (forced, reason) { + var _this = this; + forced = !!forced; + console.info('Leaving Session (forced=' + forced + ')'); + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', function (error, response) { + if (error) { + console.error(error); + } + _this.openvidu.closeWs(); + }); + } + else { + this.openvidu.closeWs(); + } + this.stopPublisherStream(reason); + if (!this.connection.disposed) { + var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehavior(); + } + } + else { + console.warn('You were not connected to the session ' + this.sessionId); + } + }; + Session.prototype.connectAux = function (token) { + var _this = this; + return new Promise(function (resolve, reject) { + _this.openvidu.startWs(function (error) { + if (!!error) { + reject(error); + } + else { + var joinParams = { + token: (!!token) ? token : '', + session: _this.sessionId, + platform: !!platform.description ? platform.description : 'unknown', + metadata: !!_this.options.metadata ? _this.options.metadata : '', + secret: _this.openvidu.getSecret(), + recorder: _this.openvidu.getRecorder() + }; + _this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) { + if (!!error) { + reject(error); + } + else { + _this.capabilities = { + subscribe: true, + publish: _this.openvidu.role !== 'SUBSCRIBER', + forceUnpublish: _this.openvidu.role === 'MODERATOR', + forceDisconnect: _this.openvidu.role === 'MODERATOR' + }; + _this.connection = new Connection_1.Connection(_this); + _this.connection.connectionId = response.id; + _this.connection.creationTime = response.createdAt; + _this.connection.data = response.metadata; + _this.connection.rpcSessionId = response.sessionId; + var events_1 = { + connections: new Array(), + streams: new Array() + }; + var existingParticipants = response.value; + existingParticipants.forEach(function (participant) { + var connection = new Connection_1.Connection(_this, participant); + _this.remoteConnections[connection.connectionId] = connection; + events_1.connections.push(connection); + if (!!connection.stream) { + _this.remoteStreamsCreated[connection.stream.streamId] = true; + events_1.streams.push(connection.stream); + } + }); + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')]); + events_1.connections.forEach(function (connection) { + _this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]); + }); + events_1.streams.forEach(function (stream) { + _this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]); + }); + resolve(); + } + }); + } + }); + }); + }; + Session.prototype.stopPublisherStream = function (reason) { + if (!!this.connection.stream) { + this.connection.stream.disposeWebRtcPeer(); + if (this.connection.stream.isLocalStreamPublished) { + this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]); + } + } + }; + Session.prototype.stringClientMetadata = function (metadata) { + if (typeof metadata !== 'string') { + return JSON.stringify(metadata); + } + else { + return metadata; + } + }; + Session.prototype.getConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + if (_this.connection.connectionId === connectionId) { + resolve(_this.connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + } + }); + }; + Session.prototype.getRemoteConnection = function (connectionId, errorMessage) { + var _this = this; + return new Promise(function (resolve, reject) { + var connection = _this.remoteConnections[connectionId]; + if (!!connection) { + resolve(connection); + } + else { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage)); + } + }); + }; + Session.prototype.processToken = function (token) { + var match = token.match(/^(wss?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + if (!!match) { + var url = { + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + var params = token.split('?'); + var queryParams = decodeURI(params[1]) + .split('&') + .map(function (param) { return param.split('='); }) + .reduce(function (values, _a) { + var key = _a[0], value = _a[1]; + values[key] = value; + return values; + }, {}); + this.sessionId = queryParams['sessionId']; + var secret = queryParams['secret']; + var recorder = queryParams['recorder']; + var turnUsername = queryParams['turnUsername']; + var turnCredential = queryParams['turnCredential']; + var role = queryParams['role']; + var webrtcStatsInterval = queryParams['webrtcStatsInterval']; + var openviduServerVersion = queryParams['version']; + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + if (!!turnUsername && !!turnCredential) { + var stunUrl = 'stun:' + url.hostname + ':3478'; + var turnUrl1 = 'turn:' + url.hostname + ':3478'; + var turnUrl2 = turnUrl1 + '?transport=tcp'; + this.openvidu.iceServers = [ + { urls: [stunUrl] }, + { urls: [turnUrl1, turnUrl2], username: turnUsername, credential: turnCredential } + ]; + console.log('TURN temp credentials [' + turnUsername + ':' + turnCredential + ']'); + } + if (!!role) { + this.openvidu.role = role; + } + if (!!webrtcStatsInterval) { + this.openvidu.webrtcStatsInterval = +webrtcStatsInterval; + } + if (!!openviduServerVersion) { + console.info("openvidu-server version: " + openviduServerVersion); + if (openviduServerVersion !== this.openvidu.libraryVersion) { + console.error('OpenVidu Server (' + openviduServerVersion + + ') and OpenVidu Browser (' + this.openvidu.libraryVersion + + ') versions do NOT match. There may be incompatibilities'); + } + } + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + this.openvidu.httpUri = 'https://' + url.host; + } + else { + console.error('Token "' + token + '" is not valid'); + } + }; + return Session; +}()); +exports.Session = Session; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/ConnectionEvent":30,"../OpenViduInternal/Events/FilterEvent":32,"../OpenViduInternal/Events/RecordingEvent":34,"../OpenViduInternal/Events/SessionDisconnectedEvent":35,"../OpenViduInternal/Events/SignalEvent":36,"../OpenViduInternal/Events/StreamEvent":37,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"./Connection":18,"./Filter":19,"./Subscriber":26,"platform":8,"wolfy87-eventemitter":15}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Filter_1 = require("./Filter"); +var Subscriber_1 = require("./Subscriber"); +var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); +var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); +var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); +var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); +var EventEmitter = require("wolfy87-eventemitter"); +var hark = require("hark"); +var platform = require("platform"); +var Stream = (function () { + function Stream(session, options) { + var _this = this; + this.ee = new EventEmitter(); + this.isSubscribeToRemote = false; + this.isLocalStreamReadyToPublish = false; + this.isLocalStreamPublished = false; + this.publishedOnce = false; + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + this.volumeChangeEventEnabled = false; + this.session = session; + if (options.hasOwnProperty('id')) { + this.inboundStreamOpts = options; + this.streamId = this.inboundStreamOpts.id; + this.creationTime = this.inboundStreamOpts.createdAt; + this.hasAudio = this.inboundStreamOpts.hasAudio; + this.hasVideo = this.inboundStreamOpts.hasVideo; + if (this.hasAudio) { + this.audioActive = this.inboundStreamOpts.audioActive; + } + if (this.hasVideo) { + this.videoActive = this.inboundStreamOpts.videoActive; + this.typeOfVideo = (!this.inboundStreamOpts.typeOfVideo) ? undefined : this.inboundStreamOpts.typeOfVideo; + this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate; + this.videoDimensions = this.inboundStreamOpts.videoDimensions; + } + if (!!this.inboundStreamOpts.filter && (Object.keys(this.inboundStreamOpts.filter).length > 0)) { + if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) { + delete this.inboundStreamOpts.filter.lastExecMethod; + } + this.filter = this.inboundStreamOpts.filter; + } + } + else { + this.outboundStreamOpts = options; + this.hasAudio = this.isSendAudio(); + this.hasVideo = this.isSendVideo(); + if (this.hasAudio) { + this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio; + } + if (this.hasVideo) { + this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo; + this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate; + if (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) { + this.typeOfVideo = 'CUSTOM'; + } + else { + this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA'; + } + } + if (!!this.outboundStreamOpts.publisherProperties.filter) { + this.filter = this.outboundStreamOpts.publisherProperties.filter; + } + } + this.ee.on('mediastream-updated', function () { + _this.streamManager.updateMediaStream(_this.mediaStream); + console.debug('Video srcObject [' + _this.mediaStream + '] updated in stream [' + _this.streamId + ']'); + }); + } + Stream.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.once = function (type, handler) { + var _this = this; + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'", event); + } + else { + console.info("Event '" + type + "' triggered once by stream '" + _this.streamId + "'"); + } + handler(event); + }); + return this; + }; + Stream.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + return this; + }; + Stream.prototype.applyFilter = function (type, options) { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Applying filter to stream ' + _this.streamId); + options = !!options ? options : {}; + if (typeof options !== 'string') { + options = JSON.stringify(options); + } + _this.session.openvidu.sendRequest('applyFilter', { streamId: _this.streamId, type: type, options: options }, function (error, response) { + if (error) { + console.error('Error applying filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully applied on Stream ' + _this.streamId); + var oldValue = _this.filter; + _this.filter = new Filter_1.Filter(type, options); + _this.filter.stream = _this; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(_this.filter); + } + }); + }); + }; + Stream.prototype.removeFilter = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.info('Removing filter of stream ' + _this.streamId); + _this.session.openvidu.sendRequest('removeFilter', { streamId: _this.streamId }, function (error, response) { + if (error) { + console.error('Error removing filter for Stream ' + _this.streamId, error); + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter")); + } + else { + reject(error); + } + } + else { + console.info('Filter successfully removed from Stream ' + _this.streamId); + var oldValue = _this.filter; + delete _this.filter; + _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + _this.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')]); + resolve(); + } + }); + }); + }; + Stream.prototype.getMediaStream = function () { + return this.mediaStream; + }; + Stream.prototype.setMediaStream = function (mediaStream) { + this.mediaStream = mediaStream; + }; + Stream.prototype.updateMediaStreamInVideos = function () { + this.ee.emitEvent('mediastream-updated', []); + }; + Stream.prototype.getWebRtcPeer = function () { + return this.webRtcPeer; + }; + Stream.prototype.getRTCPeerConnection = function () { + return this.webRtcPeer.pc; + }; + Stream.prototype.subscribeToMyRemote = function (value) { + this.isSubscribeToRemote = value; + }; + Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) { + this.outboundStreamOpts = outboundStreamOpts; + }; + Stream.prototype.subscribe = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.initWebRtcPeerReceive() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + }; + Stream.prototype.publish = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocalStreamReadyToPublish) { + _this.initWebRtcPeerSend() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + } + else { + _this.ee.once('stream-ready-to-publish', function () { + _this.publish() + .then(function () { + resolve(); + }) + .catch(function (error) { + reject(error); + }); + }); + } + }); + }; + Stream.prototype.disposeWebRtcPeer = function () { + if (!!this.webRtcPeer) { + var isSenderAndCustomTrack = !!this.outboundStreamOpts && + typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack; + this.webRtcPeer.dispose(isSenderAndCustomTrack); + } + if (!!this.speechEvent) { + if (!!this.speechEvent.stop) { + this.speechEvent.stop(); + } + delete this.speechEvent; + } + this.stopWebRtcStats(); + console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); + }; + Stream.prototype.disposeMediaStream = function () { + if (this.mediaStream) { + this.mediaStream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this.mediaStream.getVideoTracks().forEach(function (track) { + track.stop(); + }); + delete this.mediaStream; + } + console.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed'); + }; + Stream.prototype.displayMyRemote = function () { + return this.isSubscribeToRemote; + }; + Stream.prototype.isSendAudio = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.audioSource !== null && + this.outboundStreamOpts.publisherProperties.audioSource !== false); + }; + Stream.prototype.isSendVideo = function () { + return (!!this.outboundStreamOpts && + this.outboundStreamOpts.publisherProperties.videoSource !== null && + this.outboundStreamOpts.publisherProperties.videoSource !== false); + }; + Stream.prototype.isSendScreen = function () { + var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen'; + if (platform.name === 'Electron') { + screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' && + this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:'); + } + return !!this.outboundStreamOpts && screen; + }; + Stream.prototype.setSpeechEventIfNotExists = function () { + if (!this.speechEvent) { + var harkOptions = this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {}; + harkOptions.interval = (typeof harkOptions.interval === 'number') ? harkOptions.interval : 50; + harkOptions.threshold = (typeof harkOptions.threshold === 'number') ? harkOptions.threshold : -50; + this.speechEvent = hark(this.mediaStream, harkOptions); + } + }; + Stream.prototype.enableSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.on('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.on('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + }); + } + }; + Stream.prototype.enableOnceSpeakingEvents = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.publisherStartSpeakingEventEnabled) { + this.publisherStartSpeakingEventEnabled = true; + this.speechEvent.once('speaking', function () { + _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + if (!this.publisherStopSpeakingEventEnabled) { + this.publisherStopSpeakingEventEnabled = true; + this.speechEvent.once('stopped_speaking', function () { + _this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); + _this.disableSpeakingEvents(); + }); + } + }; + Stream.prototype.disableSpeakingEvents = function () { + if (!!this.speechEvent) { + if (this.volumeChangeEventEnabled) { + this.speechEvent.off('speaking'); + this.speechEvent.off('stopped_speaking'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.publisherStartSpeakingEventEnabled = false; + this.publisherStopSpeakingEventEnabled = false; + }; + Stream.prototype.enableVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.on('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.enableOnceVolumeChangeEvent = function () { + var _this = this; + this.setSpeechEventIfNotExists(); + if (!this.volumeChangeEventEnabled) { + this.volumeChangeEventEnabled = true; + this.speechEvent.once('volume_change', function (harkEvent) { + var oldValue = _this.speechEvent.oldVolumeValue; + var value = { newValue: harkEvent, oldValue: oldValue }; + _this.speechEvent.oldVolumeValue = harkEvent; + _this.disableVolumeChangeEvent(); + _this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]); + }); + } + }; + Stream.prototype.disableVolumeChangeEvent = function () { + if (!!this.speechEvent) { + if (this.session.speakingEventsEnabled) { + this.speechEvent.off('volume_change'); + } + else { + this.speechEvent.stop(); + delete this.speechEvent; + } + } + this.volumeChangeEventEnabled = false; + }; + Stream.prototype.isLocal = function () { + return (!this.inboundStreamOpts && !!this.outboundStreamOpts); + }; + Stream.prototype.getSelectedIceCandidate = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.webRtcStats.getSelectedIceCandidateInfo() + .then(function (report) { return resolve(report); }) + .catch(function (error) { return reject(error); }); + }); + }; + Stream.prototype.getRemoteIceCandidateList = function () { + return this.webRtcPeer.remoteCandidatesQueue; + }; + Stream.prototype.getLocalIceCandidateList = function () { + return this.webRtcPeer.localCandidatesQueue; + }; + Stream.prototype.initWebRtcPeerSend = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var userMediaConstraints = { + audio: _this.isSendAudio(), + video: _this.isSendVideo() + }; + var options = { + mediaStream: _this.mediaStream, + mediaConstraints: userMediaConstraints, + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to publish as ' + + _this.streamId, sdpOfferParam); + var typeOfVideo = ''; + if (_this.isSendVideo()) { + typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && _this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (_this.isSendScreen() ? 'SCREEN' : 'CAMERA'); + } + _this.session.openvidu.sendRequest('publishVideo', { + sdpOffer: sdpOfferParam, + doLoopback: _this.displayMyRemote() || false, + hasAudio: _this.isSendAudio(), + hasVideo: _this.isSendVideo(), + audioActive: _this.audioActive, + videoActive: _this.videoActive, + typeOfVideo: typeOfVideo, + frameRate: !!_this.frameRate ? _this.frameRate : -1, + videoDimensions: JSON.stringify(_this.videoDimensions), + filter: _this.outboundStreamOpts.publisherProperties.filter + }, function (error, response) { + if (error) { + if (error.code === 401) { + reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); + } + else { + reject('Error on publishVideo: ' + JSON.stringify(error)); + } + } + else { + _this.webRtcPeer.processAnswer(response.sdpAnswer, false) + .then(function () { + _this.streamId = response.id; + _this.creationTime = response.createdAt; + _this.isLocalStreamPublished = true; + _this.publishedOnce = true; + if (_this.displayMyRemote()) { + _this.remotePeerSuccessfullyEstablished(); + } + _this.ee.emitEvent('stream-created-by-publisher', []); + _this.initWebRtcStats(); + resolve(); + }) + .catch(function (error) { + reject(error); + }); + console.info("'Publisher' successfully published to session"); + } + }); + }; + if (_this.displayMyRemote()) { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(options); + } + else { + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(options); + } + _this.webRtcPeer.generateOffer().then(function (offer) { + successCallback(offer); + }).catch(function (error) { + reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.initWebRtcPeerReceive = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerConstraints = { + audio: _this.inboundStreamOpts.hasAudio, + video: _this.inboundStreamOpts.hasVideo + }; + console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer", offerConstraints); + var options = { + onicecandidate: _this.connection.sendIceCandidate.bind(_this.connection), + mediaConstraints: offerConstraints, + iceServers: _this.getIceServersConf(), + simulcast: false + }; + var successCallback = function (sdpOfferParam) { + console.debug('Sending SDP offer to subscribe to ' + + _this.streamId, sdpOfferParam); + _this.session.openvidu.sendRequest('receiveVideoFrom', { + sender: _this.streamId, + sdpOffer: sdpOfferParam + }, function (error, response) { + if (error) { + reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + } + else { + if (_this.session.isFirstIonicIosSubscriber) { + _this.session.isFirstIonicIosSubscriber = false; + setTimeout(function () { + _this.session.countDownForIonicIosSubscribersActive = false; + }, 400); + } + var needsTimeoutOnProcessAnswer = _this.session.countDownForIonicIosSubscribersActive; + _this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(function () { + _this.remotePeerSuccessfullyEstablished(); + _this.initWebRtcStats(); + resolve(); + }).catch(function (error) { + reject(error); + }); + } + }); + }; + _this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(options); + _this.webRtcPeer.generateOffer() + .then(function (offer) { + successCallback(offer); + }) + .catch(function (error) { + reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); + }); + }); + }; + Stream.prototype.remotePeerSuccessfullyEstablished = function () { + if (platform['isIonicIos']) { + var pc1 = this.webRtcPeer.pc; + this.mediaStream = pc1.getRemoteStreams()[0]; + } + else { + this.mediaStream = new MediaStream(); + var receiver = void 0; + for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) { + receiver = _a[_i]; + if (!!receiver.track) { + this.mediaStream.addTrack(receiver.track); + } + } + } + console.debug('Peer remote stream', this.mediaStream); + if (!!this.mediaStream) { + if (this.streamManager instanceof Subscriber_1.Subscriber) { + if (!!this.mediaStream.getAudioTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToAudio); + this.mediaStream.getAudioTracks()[0].enabled = enabled; + } + if (!!this.mediaStream.getVideoTracks()[0]) { + var enabled = !!(this.streamManager.properties.subscribeToVideo); + this.mediaStream.getVideoTracks()[0].enabled = enabled; + } + } + this.updateMediaStreamInVideos(); + if (!this.displayMyRemote() && !!this.mediaStream.getAudioTracks()[0] && this.session.speakingEventsEnabled) { + this.enableSpeakingEvents(); + } + } + }; + Stream.prototype.initWebRtcStats = function () { + this.webRtcStats = new WebRtcStats_1.WebRtcStats(this); + this.webRtcStats.initWebRtcStats(); + }; + Stream.prototype.stopWebRtcStats = function () { + if (!!this.webRtcStats && this.webRtcStats.isEnabled()) { + this.webRtcStats.stopWebRtcStats(); + } + }; + Stream.prototype.getIceServersConf = function () { + var returnValue; + if (!!this.session.openvidu.advancedConfiguration.iceServers) { + returnValue = this.session.openvidu.advancedConfiguration.iceServers === 'freeice' ? + undefined : + this.session.openvidu.advancedConfiguration.iceServers; + } + else if (this.session.openvidu.iceServers) { + returnValue = this.session.openvidu.iceServers; + } + else { + returnValue = undefined; + } + return returnValue; + }; + Stream.prototype.gatherStatsForPeer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.isLocal()) { + _this.getRTCPeerConnection().getSenders().forEach(function (sender) { return sender.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'outbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesEncoded'] = report.framesEncoded; + } + finalReport['packetsSent'] = report.packetsSent; + finalReport['bytesSent'] = report.bytesSent; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + else { + _this.getRTCPeerConnection().getReceivers().forEach(function (receiver) { return receiver.getStats() + .then(function (response) { + response.forEach(function (report) { + if (_this.isReportWanted(report)) { + var finalReport = {}; + finalReport['type'] = report.type; + finalReport['timestamp'] = report.timestamp; + finalReport['id'] = report.id; + if (report.type === 'inbound-rtp') { + finalReport['ssrc'] = report.ssrc; + finalReport['firCount'] = report.firCount; + finalReport['pliCount'] = report.pliCount; + finalReport['nackCount'] = report.nackCount; + finalReport['qpSum'] = report.qpSum; + if (!!report.kind) { + finalReport['mediaType'] = report.kind; + } + else if (!!report.mediaType) { + finalReport['mediaType'] = report.mediaType; + } + else { + finalReport['mediaType'] = (report.id.indexOf('VideoStream') !== -1) ? 'video' : 'audio'; + } + if (finalReport['mediaType'] === 'video') { + finalReport['framesDecoded'] = report.framesDecoded; + } + finalReport['packetsReceived'] = report.packetsReceived; + finalReport['packetsLost'] = report.packetsLost; + finalReport['jitter'] = report.jitter; + finalReport['bytesReceived'] = report.bytesReceived; + } + if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) { + finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate; + finalReport['rtt'] = report.currentRoundTripTime; + finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived; + } + if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') { + } + console.log(finalReport); + } + }); + }); }); + } + }); + }; + Stream.prototype.isReportWanted = function (report) { + return report.type === 'inbound-rtp' && !this.isLocal() || + report.type === 'outbound-rtp' && this.isLocal() || + (report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0); + }; + return Stream; +}()); +exports.Stream = Stream; + +},{"../OpenViduInternal/Enums/OpenViduError":28,"../OpenViduInternal/Events/PublisherSpeakingEvent":33,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/StreamPropertyChangedEvent":39,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":52,"../OpenViduInternal/WebRtcStats/WebRtcStats":53,"./Filter":19,"./Subscriber":26,"hark":5,"platform":8,"wolfy87-eventemitter":15}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent"); +var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); +var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); +var EventEmitter = require("wolfy87-eventemitter"); +var platform = require("platform"); +var StreamManager = (function () { + function StreamManager(stream, targetElement) { + var _this = this; + this.videos = []; + this.lazyLaunchVideoElementCreatedEvent = false; + this.ee = new EventEmitter(); + this.stream = stream; + this.stream.streamManager = this; + this.remote = !this.stream.isLocal(); + if (!!targetElement) { + var targEl = void 0; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + if (!!targEl) { + this.firstVideoElement = { + targetElement: targEl, + video: document.createElement('video'), + id: '', + canplayListenerAdded: false + }; + if (platform.name === 'Safari') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } + this.targetElement = targEl; + this.element = targEl; + } + } + this.canPlayListener = function () { + if (_this.stream.isLocal()) { + if (!_this.stream.displayMyRemote()) { + console.info("Your local 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + else { + console.info("Your own remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'remoteVideoPlaying')]); + } + } + else { + console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); + _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); + } + _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]); + }; + } + StreamManager.prototype.on = function (type, handler) { + var _this = this; + this.ee.on(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'", event); + } + else { + console.info("Event '" + type + "' triggered by '" + (_this.remote ? 'Subscriber' : 'Publisher') + "'"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = false; + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.once = function (type, handler) { + this.ee.once(type, function (event) { + if (event) { + console.info("Event '" + type + "' triggered once", event); + } + else { + console.info("Event '" + type + "' triggered once"); + } + handler(event); + }); + if (type === 'videoElementCreated') { + if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) { + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]); + } + } + if (type === 'streamPlaying' || type === 'videoPlaying') { + if (this.videos[0] && this.videos[0].video && + this.videos[0].video.currentTime > 0 && + this.videos[0].video.paused === false && + this.videos[0].video.ended === false && + this.videos[0].video.readyState === 4) { + this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]); + this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); + } + } + if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) { + this.stream.enableOnceVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.off = function (type, handler) { + if (!handler) { + this.ee.removeAllListeners(type); + } + else { + this.ee.off(type, handler); + } + if (type === 'streamAudioVolumeChange') { + this.stream.disableVolumeChangeEvent(); + } + return this; + }; + StreamManager.prototype.addVideoElement = function (video) { + this.initializeVideoProperties(video); + if (this.stream.isLocal() && this.stream.displayMyRemote()) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + for (var _i = 0, _a = this.videos; _i < _a.length; _i++) { + var v = _a[_i]; + if (v.video === video) { + return 0; + } + } + var returnNumber = 1; + for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) { + var streamManager = _c[_b]; + if (streamManager.disassociateVideo(video)) { + returnNumber = -1; + break; + } + } + this.stream.session.streamManagers.forEach(function (streamManager) { + streamManager.disassociateVideo(video); + }); + this.pushNewStreamManagerVideo({ + video: video, + id: video.id, + canplayListenerAdded: false + }); + console.info('New video element associated to ', this); + return returnNumber; + }; + StreamManager.prototype.createVideoElement = function (targetElement, insertMode) { + var targEl; + if (typeof targetElement === 'string') { + targEl = document.getElementById(targetElement); + if (!targEl) { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + } + else if (targetElement instanceof HTMLElement) { + targEl = targetElement; + } + else { + throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement); + } + var video = document.createElement('video'); + this.initializeVideoProperties(video); + var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND; + switch (insMode) { + case VideoInsertMode_1.VideoInsertMode.AFTER: + targEl.parentNode.insertBefore(video, targEl.nextSibling); + break; + case VideoInsertMode_1.VideoInsertMode.APPEND: + targEl.appendChild(video); + break; + case VideoInsertMode_1.VideoInsertMode.BEFORE: + targEl.parentNode.insertBefore(video, targEl); + break; + case VideoInsertMode_1.VideoInsertMode.PREPEND: + targEl.insertBefore(video, targEl.childNodes[0]); + break; + case VideoInsertMode_1.VideoInsertMode.REPLACE: + targEl.parentNode.replaceChild(video, targEl); + break; + default: + insMode = VideoInsertMode_1.VideoInsertMode.APPEND; + targEl.appendChild(video); + break; + } + var v = { + targetElement: targEl, + video: video, + insertMode: insMode, + id: video.id, + canplayListenerAdded: false + }; + this.pushNewStreamManagerVideo(v); + this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]); + this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement; + return video; + }; + StreamManager.prototype.initializeVideoProperties = function (video) { + if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { + if (video.srcObject !== this.stream.getMediaStream()) { + video.srcObject = this.stream.getMediaStream(); + } + } + video.autoplay = true; + video.controls = false; + if (platform.name === 'Safari') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { + video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; + if (!this.id && !!this.targetElement) { + this.id = video.id; + } + } + if (!this.remote && !this.stream.displayMyRemote()) { + video.muted = true; + if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) { + this.removeMirrorVideo(video); + } + else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) { + this.mirrorVideo(video); + } + } + }; + StreamManager.prototype.removeAllVideos = function () { + var _this = this; + for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) { + if (this.stream.session.streamManagers[i] === this) { + this.stream.session.streamManagers.splice(i, 1); + } + } + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener); + streamManagerVideo.canplayListenerAdded = false; + if (!!streamManagerVideo.targetElement) { + streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video); + _this.ee.emitEvent('videoElementDestroyed', [new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')]); + } + streamManagerVideo.video.srcObject = null; + _this.videos.filter(function (v) { return !v.targetElement; }); + }); + }; + StreamManager.prototype.disassociateVideo = function (video) { + var disassociated = false; + for (var i = 0; i < this.videos.length; i++) { + if (this.videos[i].video === video) { + this.videos[i].video.removeEventListener('canplay', this.canPlayListener); + this.videos.splice(i, 1); + disassociated = true; + console.info('Video element disassociated from ', this); + break; + } + } + return disassociated; + }; + StreamManager.prototype.addPlayEventToFirstVideo = function () { + if ((!!this.videos[0]) && (!!this.videos[0].video) && (!this.videos[0].canplayListenerAdded)) { + this.videos[0].video.addEventListener('canplay', this.canPlayListener); + this.videos[0].canplayListenerAdded = true; + } + }; + StreamManager.prototype.updateMediaStream = function (mediaStream) { + this.videos.forEach(function (streamManagerVideo) { + streamManagerVideo.video.srcObject = mediaStream; + if (platform['isIonicIos']) { + var vParent = streamManagerVideo.video.parentElement; + var newVideo = streamManagerVideo.video; + vParent.replaceChild(newVideo, streamManagerVideo.video); + streamManagerVideo.video = newVideo; + } + }); + }; + StreamManager.prototype.emitEvent = function (type, eventArray) { + this.ee.emitEvent(type, eventArray); + }; + StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) { + this.videos.push(streamManagerVideo); + this.addPlayEventToFirstVideo(); + if (this.stream.session.streamManagers.indexOf(this) === -1) { + this.stream.session.streamManagers.push(this); + } + }; + StreamManager.prototype.mirrorVideo = function (video) { + if (!platform['isIonicIos']) { + video.style.transform = 'rotateY(180deg)'; + video.style.webkitTransform = 'rotateY(180deg)'; + } + }; + StreamManager.prototype.removeMirrorVideo = function (video) { + video.style.transform = 'unset'; + video.style.webkitTransform = 'unset'; + }; + return StreamManager; +}()); +exports.StreamManager = StreamManager; + +},{"../OpenViduInternal/Enums/VideoInsertMode":29,"../OpenViduInternal/Events/StreamManagerEvent":38,"../OpenViduInternal/Events/VideoElementEvent":40,"platform":8,"wolfy87-eventemitter":15}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var StreamManager_1 = require("./StreamManager"); +var Subscriber = (function (_super) { + __extends(Subscriber, _super); + function Subscriber(stream, targEl, properties) { + var _this = _super.call(this, stream, targEl) || this; + _this.element = _this.targetElement; + _this.stream = stream; + _this.properties = properties; + return _this; + } + Subscriber.prototype.subscribeToAudio = function (value) { + this.stream.getMediaStream().getAudioTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream'); + return this; + }; + Subscriber.prototype.subscribeToVideo = function (value) { + this.stream.getMediaStream().getVideoTracks().forEach(function (track) { + track.enabled = value; + }); + console.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream'); + return this; + }; + return Subscriber; +}(StreamManager_1.StreamManager)); +exports.Subscriber = Subscriber; + +},{"./StreamManager":25}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LocalRecorderState; +(function (LocalRecorderState) { + LocalRecorderState["READY"] = "READY"; + LocalRecorderState["RECORDING"] = "RECORDING"; + LocalRecorderState["PAUSED"] = "PAUSED"; + LocalRecorderState["FINISHED"] = "FINISHED"; +})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {})); + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var OpenViduErrorName; +(function (OpenViduErrorName) { + OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED"; + OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED"; + OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE"; + OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED"; + OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED"; + OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED"; + OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED"; + OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND"; + OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND"; + OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET"; + OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR"; + OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED"; + OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED"; + OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR"; +})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {})); +var OpenViduError = (function () { + function OpenViduError(name, message) { + this.name = name; + this.message = message; + } + return OpenViduError; +}()); +exports.OpenViduError = OpenViduError; + +},{}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VideoInsertMode; +(function (VideoInsertMode) { + VideoInsertMode["AFTER"] = "AFTER"; + VideoInsertMode["APPEND"] = "APPEND"; + VideoInsertMode["BEFORE"] = "BEFORE"; + VideoInsertMode["PREPEND"] = "PREPEND"; + VideoInsertMode["REPLACE"] = "REPLACE"; +})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {})); + +},{}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var ConnectionEvent = (function (_super) { + __extends(ConnectionEvent, _super); + function ConnectionEvent(cancelable, target, type, connection, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.connection = connection; + _this.reason = reason; + return _this; + } + ConnectionEvent.prototype.callDefaultBehavior = function () { }; + return ConnectionEvent; +}(Event_1.Event)); +exports.ConnectionEvent = ConnectionEvent; + +},{"./Event":31}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Event = (function () { + function Event(cancelable, target, type) { + this.hasBeenPrevented = false; + this.cancelable = cancelable; + this.target = target; + this.type = type; + } + Event.prototype.isDefaultPrevented = function () { + return this.hasBeenPrevented; + }; + Event.prototype.preventDefault = function () { + this.callDefaultBehavior = function () { }; + this.hasBeenPrevented = true; + }; + return Event; +}()); +exports.Event = Event; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var FilterEvent = (function (_super) { + __extends(FilterEvent, _super); + function FilterEvent(target, eventType, data) { + var _this = _super.call(this, false, target, eventType) || this; + _this.data = data; + return _this; + } + FilterEvent.prototype.callDefaultBehavior = function () { }; + return FilterEvent; +}(Event_1.Event)); +exports.FilterEvent = FilterEvent; + +},{"./Event":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var PublisherSpeakingEvent = (function (_super) { + __extends(PublisherSpeakingEvent, _super); + function PublisherSpeakingEvent(target, type, connection, streamId) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.connection = connection; + _this.streamId = streamId; + return _this; + } + PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { }; + return PublisherSpeakingEvent; +}(Event_1.Event)); +exports.PublisherSpeakingEvent = PublisherSpeakingEvent; + +},{"./Event":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var RecordingEvent = (function (_super) { + __extends(RecordingEvent, _super); + function RecordingEvent(target, type, id, name, reason) { + var _this = _super.call(this, false, target, type) || this; + _this.id = id; + if (name !== id) { + _this.name = name; + } + _this.reason = reason; + return _this; + } + RecordingEvent.prototype.callDefaultBehavior = function () { }; + return RecordingEvent; +}(Event_1.Event)); +exports.RecordingEvent = RecordingEvent; + +},{"./Event":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SessionDisconnectedEvent = (function (_super) { + __extends(SessionDisconnectedEvent, _super); + function SessionDisconnectedEvent(target, reason) { + var _this = _super.call(this, true, target, 'sessionDisconnected') || this; + _this.reason = reason; + return _this; + } + SessionDisconnectedEvent.prototype.callDefaultBehavior = function () { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + var session = this.target; + for (var connectionId in session.remoteConnections) { + if (!!session.remoteConnections[connectionId].stream) { + session.remoteConnections[connectionId].stream.disposeWebRtcPeer(); + session.remoteConnections[connectionId].stream.disposeMediaStream(); + if (session.remoteConnections[connectionId].stream.streamManager) { + session.remoteConnections[connectionId].stream.streamManager.removeAllVideos(); + } + delete session.remoteStreamsCreated[session.remoteConnections[connectionId].stream.streamId]; + session.remoteConnections[connectionId].dispose(); + } + delete session.remoteConnections[connectionId]; + } + }; + return SessionDisconnectedEvent; +}(Event_1.Event)); +exports.SessionDisconnectedEvent = SessionDisconnectedEvent; + +},{"./Event":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var SignalEvent = (function (_super) { + __extends(SignalEvent, _super); + function SignalEvent(target, type, data, from) { + var _this = _super.call(this, false, target, type) || this; + _this.type = type; + _this.data = data; + _this.from = from; + return _this; + } + SignalEvent.prototype.callDefaultBehavior = function () { }; + return SignalEvent; +}(Event_1.Event)); +exports.SignalEvent = SignalEvent; + +},{"./Event":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var Publisher_1 = require("../../OpenVidu/Publisher"); +var Session_1 = require("../../OpenVidu/Session"); +var StreamEvent = (function (_super) { + __extends(StreamEvent, _super); + function StreamEvent(cancelable, target, type, stream, reason) { + var _this = _super.call(this, cancelable, target, type) || this; + _this.stream = stream; + _this.reason = reason; + return _this; + } + StreamEvent.prototype.callDefaultBehavior = function () { + if (this.type === 'streamDestroyed') { + if (this.target instanceof Session_1.Session) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'"); + this.stream.disposeWebRtcPeer(); + } + else if (this.target instanceof Publisher_1.Publisher) { + console.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'"); + clearInterval(this.target.screenShareResizeInterval); + this.stream.isLocalStreamReadyToPublish = false; + var openviduPublishers = this.target.openvidu.publishers; + for (var i = 0; i < openviduPublishers.length; i++) { + if (openviduPublishers[i] === this.target) { + openviduPublishers.splice(i, 1); + break; + } + } + } + this.stream.disposeMediaStream(); + if (this.stream.streamManager) + this.stream.streamManager.removeAllVideos(); + delete this.stream.session.remoteStreamsCreated[this.stream.streamId]; + var remoteConnection = this.stream.session.remoteConnections[this.stream.connection.connectionId]; + if (!!remoteConnection && !!remoteConnection.options) { + var streamOptionsServer = remoteConnection.options.streams; + for (var i = streamOptionsServer.length - 1; i >= 0; --i) { + if (streamOptionsServer[i].id === this.stream.streamId) { + streamOptionsServer.splice(i, 1); + } + } + } + } + }; + return StreamEvent; +}(Event_1.Event)); +exports.StreamEvent = StreamEvent; + +},{"../../OpenVidu/Publisher":22,"../../OpenVidu/Session":23,"./Event":31}],38:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamManagerEvent = (function (_super) { + __extends(StreamManagerEvent, _super); + function StreamManagerEvent(target, type, value) { + var _this = _super.call(this, false, target, type) || this; + _this.value = value; + return _this; + } + StreamManagerEvent.prototype.callDefaultBehavior = function () { }; + return StreamManagerEvent; +}(Event_1.Event)); +exports.StreamManagerEvent = StreamManagerEvent; + +},{"./Event":31}],39:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var StreamPropertyChangedEvent = (function (_super) { + __extends(StreamPropertyChangedEvent, _super); + function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) { + var _this = _super.call(this, false, target, 'streamPropertyChanged') || this; + _this.stream = stream; + _this.changedProperty = changedProperty; + _this.newValue = newValue; + _this.oldValue = oldValue; + _this.reason = reason; + return _this; + } + StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { }; + return StreamPropertyChangedEvent; +}(Event_1.Event)); +exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent; + +},{"./Event":31}],40:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Event_1 = require("./Event"); +var VideoElementEvent = (function (_super) { + __extends(VideoElementEvent, _super); + function VideoElementEvent(element, target, type) { + var _this = _super.call(this, false, target, type) || this; + _this.element = element; + return _this; + } + VideoElementEvent.prototype.callDefaultBehavior = function () { }; + return VideoElementEvent; +}(Event_1.Event)); +exports.VideoElementEvent = VideoElementEvent; + +},{"./Event":31}],41:[function(require,module,exports){ +function Mapper() { + var sources = {}; + this.forEach = function (callback) { + for (var key in sources) { + var source = sources[key]; + for (var key2 in source) + callback(source[key2]); + } + ; + }; + this.get = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return undefined; + return ids[id]; + }; + this.remove = function (id, source) { + var ids = sources[source]; + if (ids == undefined) + return; + delete ids[id]; + for (var i in ids) { + return false; + } + delete sources[source]; + }; + this.set = function (value, id, source) { + if (value == undefined) + return this.remove(id, source); + var ids = sources[source]; + if (ids == undefined) + sources[source] = ids = {}; + ids[id] = value; + }; +} +; +Mapper.prototype.pop = function (id, source) { + var value = this.get(id, source); + if (value == undefined) + return undefined; + this.remove(id, source); + return value; +}; +module.exports = Mapper; + +},{}],42:[function(require,module,exports){ +var JsonRpcClient = require('./jsonrpcclient'); +exports.JsonRpcClient = JsonRpcClient; + +},{"./jsonrpcclient":43}],43:[function(require,module,exports){ +var RpcBuilder = require('../'); +var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); +Date.now = Date.now || function () { + return +new Date; +}; +var PING_INTERVAL = 5000; +var RECONNECTING = 'RECONNECTING'; +var CONNECTED = 'CONNECTED'; +var DISCONNECTED = 'DISCONNECTED'; +var Logger = console; +function JsonRpcClient(configuration) { + var self = this; + var wsConfig = configuration.ws; + var notReconnectIfNumLessThan = -1; + var pingNextNum = 0; + var enabledPings = true; + var pingPongStarted = false; + var pingInterval; + var status = DISCONNECTED; + var onreconnecting = wsConfig.onreconnecting; + var onreconnected = wsConfig.onreconnected; + var onconnected = wsConfig.onconnected; + var onerror = wsConfig.onerror; + configuration.rpc.pull = function (params, request) { + request.reply(null, "push"); + }; + wsConfig.onreconnecting = function () { + Logger.debug("--------- ONRECONNECTING -----------"); + if (status === RECONNECTING) { + Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); + return; + } + stopPing(); + status = RECONNECTING; + if (onreconnecting) { + onreconnecting(); + } + }; + wsConfig.onreconnected = function () { + Logger.debug("--------- ONRECONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + updateNotReconnectIfLessThan(); + if (onreconnected) { + onreconnected(); + } + }; + wsConfig.onconnected = function () { + Logger.debug("--------- ONCONNECTED -----------"); + if (status === CONNECTED) { + Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); + return; + } + status = CONNECTED; + enabledPings = true; + usePing(); + if (onconnected) { + onconnected(); + } + }; + wsConfig.onerror = function (error) { + Logger.debug("--------- ONERROR -----------"); + status = DISCONNECTED; + stopPing(); + if (onerror) { + onerror(error); + } + }; + var ws = new WebSocketWithReconnection(wsConfig); + Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); + var rpcBuilderOptions = { + request_timeout: configuration.rpc.requestTimeout, + ping_request_timeout: configuration.rpc.heartbeatRequestTimeout + }; + var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { + Logger.debug('Received request: ' + JSON.stringify(request)); + try { + var func = configuration.rpc[request.method]; + if (func === undefined) { + Logger.error("Method " + request.method + " not registered in client"); + } + else { + func(request.params, request); + } + } + catch (err) { + Logger.error('Exception processing request: ' + JSON.stringify(request)); + Logger.error(err); + } + }); + this.send = function (method, params, callback) { + if (method !== 'ping') { + Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); + } + var requestTime = Date.now(); + rpc.encode(method, params, function (error, result) { + if (error) { + try { + Logger.error("ERROR:" + error.message + " in Request: method:" + + method + " params:" + JSON.stringify(params) + " request:" + + error.request); + if (error.data) { + Logger.error("ERROR DATA:" + JSON.stringify(error.data)); + } + } + catch (e) { } + error.requestTime = requestTime; + } + if (callback) { + if (result != undefined && result.value !== 'pong') { + Logger.debug('Response: ' + JSON.stringify(result)); + } + callback(error, result); + } + }); + }; + function updateNotReconnectIfLessThan() { + Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + + notReconnectIfNumLessThan + ')'); + notReconnectIfNumLessThan = pingNextNum; + } + function sendPing() { + if (enabledPings) { + var params = null; + if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { + params = { + interval: configuration.heartbeat || PING_INTERVAL + }; + } + pingNextNum++; + self.send('ping', params, (function (pingNum) { + return function (error, result) { + if (error) { + Logger.debug("Error in ping request #" + pingNum + " (" + + error.message + ")"); + if (pingNum > notReconnectIfNumLessThan) { + enabledPings = false; + updateNotReconnectIfLessThan(); + Logger.debug("Server did not respond to ping message #" + + pingNum + ". Reconnecting... "); + ws.reconnectWs(); + } + } + }; + })(pingNextNum)); + } + else { + Logger.debug("Trying to send ping, but ping is not enabled"); + } + } + function usePing() { + if (!pingPongStarted) { + Logger.debug("Starting ping (if configured)"); + pingPongStarted = true; + if (configuration.heartbeat != undefined) { + pingInterval = setInterval(sendPing, configuration.heartbeat); + sendPing(); + } + } + } + function stopPing() { + clearInterval(pingInterval); + pingPongStarted = false; + enabledPings = false; + pingNextNum = -1; + rpc.cancel(); + } + this.close = function (code, reason) { + Logger.debug("Closing with code: " + code + " because: " + reason); + if (pingInterval != undefined) { + Logger.debug("Clearing ping interval"); + clearInterval(pingInterval); + } + pingPongStarted = false; + enabledPings = false; + if (configuration.sendCloseMessage) { + Logger.debug("Sending close message"); + this.send('closeSession', null, function (error, result) { + if (error) { + Logger.error("Error sending close message: " + JSON.stringify(error)); + } + ws.close(code, reason); + }); + } + else { + ws.close(code, reason); + } + }; + this.forceClose = function (millis) { + ws.forceClose(millis); + }; + this.reconnect = function () { + ws.reconnectWs(); + }; + this.resetPing = function () { + enabledPings = true; + pingNextNum = 0; + usePing(); + }; +} +module.exports = JsonRpcClient; + +},{"../":46,"./transports/webSocketWithReconnection":45}],44:[function(require,module,exports){ +var WebSocketWithReconnection = require('./webSocketWithReconnection'); +exports.WebSocketWithReconnection = WebSocketWithReconnection; + +},{"./webSocketWithReconnection":45}],45:[function(require,module,exports){ +(function (global){ +"use strict"; +var BrowserWebSocket = global.WebSocket || global.MozWebSocket; +var Logger = console; +var MAX_RETRIES = 2000; +var RETRY_TIME_MS = 3000; +var CONNECTING = 0; +var OPEN = 1; +var CLOSING = 2; +var CLOSED = 3; +function WebSocketWithReconnection(config) { + var closing = false; + var registerMessageHandler; + var wsUri = config.uri; + var useSockJS = config.useSockJS; + var reconnecting = false; + var forcingDisconnection = false; + var ws; + if (useSockJS) { + ws = new SockJS(wsUri); + } + else { + ws = new WebSocket(wsUri); + } + ws.onopen = function () { + logConnected(ws, wsUri); + if (config.onconnected) { + config.onconnected(); + } + }; + ws.onerror = function (error) { + Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); + if (config.onerror) { + config.onerror(error); + } + }; + function logConnected(ws, wsUri) { + try { + Logger.debug("WebSocket connected to " + wsUri); + } + catch (e) { + Logger.error(e); + } + } + var reconnectionOnClose = function () { + if (ws.readyState === CLOSED) { + if (closing) { + Logger.debug("Connection closed by user"); + } + else { + Logger.debug("Connection closed unexpectecly. Reconnecting..."); + reconnectToSameUri(MAX_RETRIES, 1); + } + } + else { + Logger.debug("Close callback from previous websocket. Ignoring it"); + } + }; + ws.onclose = reconnectionOnClose; + function reconnectToSameUri(maxRetries, numRetries) { + Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); + if (numRetries === 1) { + if (reconnecting) { + Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection."); + return; + } + else { + reconnecting = true; + } + if (config.onreconnecting) { + config.onreconnecting(); + } + } + if (forcingDisconnection) { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + else { + if (config.newWsUriOnReconnection) { + config.newWsUriOnReconnection(function (error, newWsUri) { + if (error) { + Logger.debug(error); + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + else { + reconnectToNewUri(maxRetries, numRetries, newWsUri); + } + }); + } + else { + reconnectToNewUri(maxRetries, numRetries, wsUri); + } + } + } + function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { + Logger.debug("Reconnection attempt #" + numRetries); + ws.close(); + wsUri = reconnectWsUri || wsUri; + var newWs; + if (useSockJS) { + newWs = new SockJS(wsUri); + } + else { + newWs = new WebSocket(wsUri); + } + newWs.onopen = function () { + Logger.debug("Reconnected after " + numRetries + " attempts..."); + logConnected(newWs, wsUri); + reconnecting = false; + registerMessageHandler(); + if (config.onreconnected()) { + config.onreconnected(); + } + newWs.onclose = reconnectionOnClose; + }; + var onErrorOrClose = function (error) { + Logger.warn("Reconnection error: ", error); + if (numRetries === maxRetries) { + if (config.ondisconnect) { + config.ondisconnect(); + } + } + else { + setTimeout(function () { + reconnectToSameUri(maxRetries, numRetries + 1); + }, RETRY_TIME_MS); + } + }; + newWs.onerror = onErrorOrClose; + ws = newWs; + } + this.close = function () { + closing = true; + ws.close(); + }; + this.forceClose = function (millis) { + Logger.debug("Testing: Force WebSocket close"); + if (millis) { + Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); + var goodWsUri = wsUri; + wsUri = "wss://21.234.12.34.4:443/"; + forcingDisconnection = true; + setTimeout(function () { + Logger.debug("Testing: Recover good wsUri " + goodWsUri); + wsUri = goodWsUri; + forcingDisconnection = false; + }, millis); + } + ws.close(); + }; + this.reconnectWs = function () { + Logger.debug("reconnectWs"); + reconnectToSameUri(MAX_RETRIES, 1); + }; + this.send = function (message) { + ws.send(message); + }; + this.addEventListener = function (type, callback) { + registerMessageHandler = function () { + ws.addEventListener(type, callback); + }; + registerMessageHandler(); + }; +} +module.exports = WebSocketWithReconnection; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],46:[function(require,module,exports){ +var defineProperty_IE8 = false; +if (Object.defineProperty) { + try { + Object.defineProperty({}, "x", {}); + } + catch (e) { + defineProperty_IE8 = true; + } +} +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} +var EventEmitter = require('events').EventEmitter; +var inherits = require('inherits'); +var packers = require('./packers'); +var Mapper = require('./Mapper'); +var BASE_TIMEOUT = 5000; +function unifyResponseMethods(responseMethods) { + if (!responseMethods) + return {}; + for (var key in responseMethods) { + var value = responseMethods[key]; + if (typeof value == 'string') + responseMethods[key] = + { + response: value + }; + } + ; + return responseMethods; +} +; +function unifyTransport(transport) { + if (!transport) + return; + if (transport instanceof Function) + return { send: transport }; + if (transport.send instanceof Function) + return transport; + if (transport.postMessage instanceof Function) { + transport.send = transport.postMessage; + return transport; + } + if (transport.write instanceof Function) { + transport.send = transport.write; + return transport; + } + if (transport.onmessage !== undefined) + return; + if (transport.pause instanceof Function) + return; + throw new SyntaxError("Transport is not a function nor a valid object"); +} +; +function RpcNotification(method, params) { + if (defineProperty_IE8) { + this.method = method; + this.params = params; + } + else { + Object.defineProperty(this, 'method', { value: method, enumerable: true }); + Object.defineProperty(this, 'params', { value: params, enumerable: true }); + } +} +; +function RpcBuilder(packer, options, transport, onRequest) { + var self = this; + if (!packer) + throw new SyntaxError('Packer is not defined'); + if (!packer.pack || !packer.unpack) + throw new SyntaxError('Packer is invalid'); + var responseMethods = unifyResponseMethods(packer.responseMethods); + if (options instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = options; + transport = undefined; + options = undefined; + } + ; + if (options && options.send instanceof Function) { + if (transport && !(transport instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + onRequest = transport; + transport = options; + options = undefined; + } + ; + if (transport instanceof Function) { + if (onRequest != undefined) + throw new SyntaxError("There can't be parameters after onRequest"); + onRequest = transport; + transport = undefined; + } + ; + if (transport && transport.send instanceof Function) + if (onRequest && !(onRequest instanceof Function)) + throw new SyntaxError("Only a function can be after transport"); + options = options || {}; + EventEmitter.call(this); + if (onRequest) + this.on('request', onRequest); + if (defineProperty_IE8) + this.peerID = options.peerID; + else + Object.defineProperty(this, 'peerID', { value: options.peerID }); + var max_retries = options.max_retries || 0; + function transportMessage(event) { + self.decode(event.data || event); + } + ; + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + if (transport) { + if (transport.removeEventListener) + transport.removeEventListener('message', transportMessage); + else if (transport.removeListener) + transport.removeListener('data', transportMessage); + } + ; + if (value) { + if (value.addEventListener) + value.addEventListener('message', transportMessage); + else if (value.addListener) + value.addListener('data', transportMessage); + } + ; + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + this.setTransport(transport); + var request_timeout = options.request_timeout || BASE_TIMEOUT; + var ping_request_timeout = options.ping_request_timeout || request_timeout; + var response_timeout = options.response_timeout || BASE_TIMEOUT; + var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT; + var requestID = 0; + var requests = new Mapper(); + var responses = new Mapper(); + var processedResponses = new Mapper(); + var message2Key = {}; + function storeResponse(message, id, dest) { + var response = { + message: message, + timeout: setTimeout(function () { + responses.remove(id, dest); + }, response_timeout) + }; + responses.set(response, id, dest); + } + ; + function storeProcessedResponse(ack, from) { + var timeout = setTimeout(function () { + processedResponses.remove(ack, from); + }, duplicates_timeout); + processedResponses.set(timeout, ack, from); + } + ; + function RpcRequest(method, params, id, from, transport) { + RpcNotification.call(this, method, params); + this.getTransport = function () { + return transport; + }; + this.setTransport = function (value) { + transport = unifyTransport(value); + }; + if (!defineProperty_IE8) + Object.defineProperty(this, 'transport', { + get: this.getTransport.bind(this), + set: this.setTransport.bind(this) + }); + var response = responses.get(id, from); + if (!(transport || self.getTransport())) { + if (defineProperty_IE8) + this.duplicated = Boolean(response); + else + Object.defineProperty(this, 'duplicated', { + value: Boolean(response) + }); + } + var responseMethod = responseMethods[method]; + this.pack = packer.pack.bind(packer, this, id); + this.reply = function (error, result, transport) { + if (error instanceof Function || error && error.send instanceof Function) { + if (result != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = error; + result = null; + error = undefined; + } + else if (result instanceof Function + || result && result.send instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + transport = result; + result = null; + } + ; + transport = unifyTransport(transport); + if (response) + clearTimeout(response.timeout); + if (from != undefined) { + if (error) + error.dest = from; + if (result) + result.dest = from; + } + ; + var message; + if (error || result != undefined) { + if (self.peerID != undefined) { + if (error) + error.from = self.peerID; + else + result.from = self.peerID; + } + if (responseMethod) { + if (responseMethod.error == undefined && error) + message = + { + error: error + }; + else { + var method = error + ? responseMethod.error + : responseMethod.response; + message = + { + method: method, + params: error || result + }; + } + } + else + message = + { + error: error, + result: result + }; + message = packer.pack(message, id); + } + else if (response) + message = response.message; + else + message = packer.pack({ result: null }, id); + storeResponse(message, id, from); + transport = transport || this.getTransport() || self.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + } + ; + inherits(RpcRequest, RpcNotification); + function cancel(message) { + var key = message2Key[message]; + if (!key) + return; + delete message2Key[message]; + var request = requests.pop(key.id, key.dest); + if (!request) + return; + clearTimeout(request.timeout); + storeProcessedResponse(key.id, key.dest); + } + ; + this.cancel = function (message) { + if (message) + return cancel(message); + for (var message in message2Key) + cancel(message); + }; + this.close = function () { + var transport = this.getTransport(); + if (transport && transport.close) + transport.close(4003, "Cancel request"); + this.cancel(); + processedResponses.forEach(clearTimeout); + responses.forEach(function (response) { + clearTimeout(response.timeout); + }); + }; + this.encode = function (method, params, dest, transport, callback) { + if (params instanceof Function) { + if (dest != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = params; + transport = undefined; + dest = undefined; + params = undefined; + } + else if (dest instanceof Function) { + if (transport != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = dest; + transport = undefined; + dest = undefined; + } + else if (transport instanceof Function) { + if (callback != undefined) + throw new SyntaxError("There can't be parameters after callback"); + callback = transport; + transport = undefined; + } + ; + if (self.peerID != undefined) { + params = params || {}; + params.from = self.peerID; + } + ; + if (dest != undefined) { + params = params || {}; + params.dest = dest; + } + ; + var message = { + method: method, + params: params + }; + if (callback) { + var id = requestID++; + var retried = 0; + message = packer.pack(message, id); + function dispatchCallback(error, result) { + self.cancel(message); + callback(error, result); + } + ; + var request = { + message: message, + callback: dispatchCallback, + responseMethods: responseMethods[method] || {} + }; + var encode_transport = unifyTransport(transport); + function sendRequest(transport) { + var rt = (method === 'ping' ? ping_request_timeout : request_timeout); + request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++)); + message2Key[message] = { id: id, dest: dest }; + requests.set(request, id, dest); + transport = transport || encode_transport || self.getTransport(); + if (transport) + return transport.send(message); + return message; + } + ; + function retry(transport) { + transport = unifyTransport(transport); + console.warn(retried + ' retry for request message:', message); + var timeout = processedResponses.pop(id, dest); + clearTimeout(timeout); + return sendRequest(transport); + } + ; + function timeout() { + if (retried < max_retries) + return retry(transport); + var error = new Error('Request has timed out'); + error.request = message; + error.retry = retry; + dispatchCallback(error); + } + ; + return sendRequest(transport); + } + ; + message = packer.pack(message); + transport = transport || this.getTransport(); + if (transport) + return transport.send(message); + return message; + }; + this.decode = function (message, transport) { + if (!message) + throw new TypeError("Message is not defined"); + try { + message = packer.unpack(message); + } + catch (e) { + return console.debug(e, message); + } + ; + var id = message.id; + var ack = message.ack; + var method = message.method; + var params = message.params || {}; + var from = params.from; + var dest = params.dest; + if (self.peerID != undefined && from == self.peerID) + return; + if (id == undefined && ack == undefined) { + var notification = new RpcNotification(method, params); + if (self.emit('request', notification)) + return; + return notification; + } + ; + function processRequest() { + transport = unifyTransport(transport) || self.getTransport(); + if (transport) { + var response = responses.get(id, from); + if (response) + return transport.send(response.message); + } + ; + var idAck = (id != undefined) ? id : ack; + var request = new RpcRequest(method, params, idAck, from, transport); + if (self.emit('request', request)) + return; + return request; + } + ; + function processResponse(request, error, result) { + request.callback(error, result); + } + ; + function duplicatedResponse(timeout) { + console.warn("Response already processed", message); + clearTimeout(timeout); + storeProcessedResponse(ack, from); + } + ; + if (method) { + if (dest == undefined || dest == self.peerID) { + var request = requests.get(ack, from); + if (request) { + var responseMethods = request.responseMethods; + if (method == responseMethods.error) + return processResponse(request, params); + if (method == responseMethods.response) + return processResponse(request, null, params); + return processRequest(); + } + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + } + return processRequest(); + } + ; + var error = message.error; + var result = message.result; + if (error && error.dest && error.dest != self.peerID) + return; + if (result && result.dest && result.dest != self.peerID) + return; + var request = requests.get(ack, from); + if (!request) { + var processed = processedResponses.get(ack, from); + if (processed) + return duplicatedResponse(processed); + return console.warn("No callback was defined for this message", message); + } + ; + processResponse(request, error, result); + }; +} +; +inherits(RpcBuilder, EventEmitter); +RpcBuilder.RpcNotification = RpcNotification; +module.exports = RpcBuilder; +var clients = require('./clients'); +var transports = require('./clients/transports'); +RpcBuilder.clients = clients; +RpcBuilder.clients.transports = transports; +RpcBuilder.packers = packers; + +},{"./Mapper":41,"./clients":42,"./clients/transports":44,"./packers":49,"events":1,"inherits":6}],47:[function(require,module,exports){ +function pack(message, id) { + var result = { + jsonrpc: "2.0" + }; + if (message.method) { + result.method = message.method; + if (message.params) + result.params = message.params; + if (id != undefined) + result.id = id; + } + else if (id != undefined) { + if (message.error) { + if (message.result !== undefined) + throw new TypeError("Both result and error are defined"); + result.error = message.error; + } + else if (message.result !== undefined) + result.result = message.result; + else + throw new TypeError("No result or error is defined"); + result.id = id; + } + ; + return JSON.stringify(result); +} +; +function unpack(message) { + var result = message; + if (typeof message === 'string' || message instanceof String) { + result = JSON.parse(message); + } + var version = result.jsonrpc; + if (version !== '2.0') + throw new TypeError("Invalid JsonRPC version '" + version + "': " + message); + if (result.method == undefined) { + if (result.id == undefined) + throw new TypeError("Invalid message: " + message); + var result_defined = result.result !== undefined; + var error_defined = result.error !== undefined; + if (result_defined && error_defined) + throw new TypeError("Both result and error are defined: " + message); + if (!result_defined && !error_defined) + throw new TypeError("No result or error is defined: " + message); + result.ack = result.id; + delete result.id; + } + return result; +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],48:[function(require,module,exports){ +function pack(message) { + throw new TypeError("Not yet implemented"); +} +; +function unpack(message) { + throw new TypeError("Not yet implemented"); +} +; +exports.pack = pack; +exports.unpack = unpack; + +},{}],49:[function(require,module,exports){ +var JsonRPC = require('./JsonRPC'); +var XmlRPC = require('./XmlRPC'); +exports.JsonRPC = JsonRPC; +exports.XmlRPC = XmlRPC; + +},{"./JsonRPC":47,"./XmlRPC":48}],50:[function(require,module,exports){ +window.getScreenId = function (firefoxString, callback, custom_parameter) { + if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) { + callback({ + video: true + }); + return; + } + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: firefoxString, + mediaSource: firefoxString + } + }); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } + else { + callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack)); + } + window.removeEventListener('message', onIFrameCallback); + } + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + window.removeEventListener('message', onIFrameCallback); + } + } + if (!custom_parameter) { + setTimeout(postGetSourceIdMessage, 100); + } + else { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + } +}; +function getScreenConstraints(error, sourceId, canRequestAudioTrack) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + if (!!canRequestAudioTrack) { + screen_constraints.audio = { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + }, + optional: [] + }; + } + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + if (screen_constraints.audio && screen_constraints.audio.mandatory) { + screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId; + } + } + return screen_constraints; +} +function postGetSourceIdMessage(custom_parameter) { + if (!iframe) { + loadIFrame(function () { + postGetSourceIdMessage(custom_parameter); + }); + return; + } + if (!iframe.isLoaded) { + setTimeout(function () { + postGetSourceIdMessage(custom_parameter); + }, 100); + return; + } + if (!custom_parameter) { + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + else if (!!custom_parameter.forEach) { + iframe.contentWindow.postMessage({ + captureCustomSourceId: custom_parameter + }, '*'); + } + else { + iframe.contentWindow.postMessage({ + captureSourceIdWithAudio: true + }, '*'); + } +} +var iframe; +window.getScreenConstraints = function (callback) { + loadIFrame(function () { + getScreenId(function (error, sourceId, screen_constraints) { + if (!screen_constraints) { + screen_constraints = { + video: true + }; + } + callback(error, screen_constraints.video); + }); + }); +}; +function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + iframe = document.createElement('iframe'); + iframe.onload = function () { + iframe.isLoaded = true; + loadCallback(); + }; + iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); +} +window.getChromeExtensionStatus = function (callback) { + if (!!navigator.mozGetUserMedia) { + callback('installed-enabled'); + return; + } + window.addEventListener('message', onIFrameCallback); + function onIFrameCallback(event) { + if (!event.data) + return; + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus); + window.removeEventListener('message', onIFrameCallback); + } + } + setTimeout(postGetChromeExtensionStatusMessage, 100); +}; +function postGetChromeExtensionStatusMessage() { + if (!iframe) { + loadIFrame(postGetChromeExtensionStatusMessage); + return; + } + if (!iframe.isLoaded) { + setTimeout(postGetChromeExtensionStatusMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + getChromeExtensionStatus: true + }, '*'); +} +exports.getScreenId = getScreenId; + +},{}],51:[function(require,module,exports){ +var chromeMediaSource = 'screen'; +var sourceId; +var screenCallback; +var isFirefox = typeof window.InstallTrigger !== 'undefined'; +var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; +var isChrome = !!window.chrome && !isOpera; +window.addEventListener('message', function (event) { + if (event.origin != window.location.origin) { + return; + } + onMessageCallback(event.data); +}); +function onMessageCallback(data) { + if (data == 'PermissionDeniedError') { + if (screenCallback) + return screenCallback('PermissionDeniedError'); + else + throw new Error('PermissionDeniedError'); + } + if (data == 'rtcmulticonnection-extension-loaded') { + chromeMediaSource = 'desktop'; + } + if (data.sourceId && screenCallback) { + screenCallback(sourceId = data.sourceId, data.canRequestAudioTrack === true); + } +} +function isChromeExtensionAvailable(callback) { + if (!callback) + return; + if (chromeMediaSource == 'desktop') + return callback(true); + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback(false); + } + else + callback(true); + }, 2000); +} +function getSourceId(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('get-sourceId', '*'); +} +function getCustomSourceId(arr, callback) { + if (!arr || !arr.forEach) + throw '"arr" parameter is mandatory and it must be an array.'; + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage({ + 'get-custom-sourceId': arr + }, '*'); +} +function getSourceIdWithAudio(callback) { + if (!callback) + throw '"callback" parameter is mandatory.'; + if (sourceId) + return callback(sourceId); + screenCallback = callback; + window.postMessage('audio-plus-tab', '*'); +} +function getChromeExtensionStatus(extensionid, callback) { + if (isFirefox) + return callback('not-chrome'); + if (arguments.length != 2) { + callback = extensionid; + extensionid = 'lfcgfepafnobdloecchnfaclibenjold'; + } + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function () { + chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function () { + if (chromeMediaSource == 'screen') { + callback('installed-disabled'); + } + else + callback('installed-enabled'); + }, 2000); + }; + image.onerror = function () { + callback('not-installed'); + }; +} +function getScreenConstraintsWithAudio(callback) { + getScreenConstraints(callback, true); +} +function getScreenConstraints(callback, captureSourceIdWithAudio) { + sourceId = ''; + var firefoxScreenConstraints = { + mozMediaSource: 'window', + mediaSource: 'window' + }; + if (isFirefox) + return callback(null, firefoxScreenConstraints); + var screen_constraints = { + mandatory: { + chromeMediaSource: chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + }; + if (chromeMediaSource == 'desktop' && !sourceId) { + if (captureSourceIdWithAudio) { + getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + if (canRequestAudioTrack) { + screen_constraints.canRequestAudioTrack = true; + } + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + else { + getSourceId(function (sourceId) { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints); + }); + } + return; + } + if (chromeMediaSource == 'desktop') { + screen_constraints.mandatory.chromeMediaSourceId = sourceId; + } + callback(null, screen_constraints); +} +exports.getScreenConstraints = getScreenConstraints; +exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio; +exports.isChromeExtensionAvailable = isChromeExtensionAvailable; +exports.getChromeExtensionStatus = getChromeExtensionStatus; +exports.getSourceId = getSourceId; + +},{}],52:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var freeice = require("freeice"); +var uuid = require("uuid"); +var platform = require("platform"); +var WebRtcPeer = (function () { + function WebRtcPeer(configuration) { + var _this = this; + this.configuration = configuration; + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + this.iceCandidateList = []; + this.candidategatheringdone = false; + this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice(); + this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers }); + this.id = !!configuration.id ? configuration.id : uuid.v4(); + this.pc.onicecandidate = function (event) { + if (!!event.candidate) { + var candidate = event.candidate; + if (candidate) { + _this.localCandidatesQueue.push({ candidate: candidate.candidate }); + _this.candidategatheringdone = false; + _this.configuration.onicecandidate(event.candidate); + } + else if (!_this.candidategatheringdone) { + _this.candidategatheringdone = true; + } + } + }; + this.pc.onsignalingstatechange = function () { + if (_this.pc.signalingState === 'stable') { + while (_this.iceCandidateList.length > 0) { + _this.pc.addIceCandidate(_this.iceCandidateList.shift()); + } + } + }; + this.start(); + } + WebRtcPeer.prototype.start = function () { + var _this = this; + return new Promise(function (resolve, reject) { + if (_this.pc.signalingState === 'closed') { + reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); + } + if (!!_this.configuration.mediaStream) { + if (platform['isIonicIos']) { + var pc2 = _this.pc; + pc2.addStream(_this.configuration.mediaStream); + } + else { + for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { + var track = _a[_i]; + _this.pc.addTrack(track, _this.configuration.mediaStream); + } + } + resolve(); + } + }); + }; + WebRtcPeer.prototype.dispose = function (videoSourceIsMediaStreamTrack) { + console.debug('Disposing WebRtcPeer'); + try { + if (this.pc) { + if (this.pc.signalingState === 'closed') { + return; + } + this.remoteCandidatesQueue = []; + this.localCandidatesQueue = []; + if (platform['isIonicIos']) { + var pc1 = this.pc; + for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { + var sender = _a[_i]; + if (!videoSourceIsMediaStreamTrack) { + sender.stop(); + } + pc1.removeStream(sender); + } + for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { + var receiver = _c[_b]; + if (!!receiver.track) { + receiver.stop(); + } + } + } + else { + for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) { + var sender = _e[_d]; + if (!videoSourceIsMediaStreamTrack) { + if (!!sender.track) { + sender.track.stop(); + } + } + this.pc.removeTrack(sender); + } + for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) { + var receiver = _g[_f]; + if (!!receiver.track) { + receiver.track.stop(); + } + } + } + this.pc.close(); + } + } + catch (err) { + console.warn('Exception disposing webrtc peer ' + err); + } + }; + WebRtcPeer.prototype.generateOffer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var offerAudio, offerVideo = true; + if (!!_this.configuration.mediaConstraints) { + offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ? + _this.configuration.mediaConstraints.audio : true; + offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ? + _this.configuration.mediaConstraints.video : true; + } + var constraints = { + offerToReceiveAudio: (_this.configuration.mode !== 'sendonly' && offerAudio), + offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) + }; + console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); + if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) { + if (offerAudio) { + _this.pc.addTransceiver('audio', { + direction: _this.configuration.mode, + }); + } + if (offerVideo) { + _this.pc.addTransceiver('video', { + direction: _this.configuration.mode, + }); + } + _this.pc + .createOffer() + .then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + else { + _this.pc.createOffer(constraints).then(function (offer) { + console.debug('Created SDP offer'); + return _this.pc.setLocalDescription(offer); + }) + .then(function () { + var localDescription = _this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } + else { + reject('Local description is not defined'); + } + }) + .catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAnswer) { + var _this = this; + return new Promise(function (resolve, reject) { + var answer = { + type: 'answer', + sdp: sdpAnswer + }; + console.debug('SDP answer received, setting remote description'); + if (_this.pc.signalingState === 'closed') { + reject('RTCPeerConnection is closed'); + } + if (platform['isIonicIos']) { + if (needsTimeoutOnProcessAnswer) { + setTimeout(function () { + console.info('setRemoteDescription run after timeout for Ionic iOS device'); + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + }, 250); + } + else { + _this.pc.setRemoteDescription(new RTCSessionDescription(answer)).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + } + else { + _this.pc.setRemoteDescription(answer).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + }); + }; + WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) { + var _this = this; + return new Promise(function (resolve, reject) { + console.debug('Remote ICE candidate received', iceCandidate); + _this.remoteCandidatesQueue.push(iceCandidate); + switch (_this.pc.signalingState) { + case 'closed': + reject(new Error('PeerConnection object is closed')); + break; + case 'stable': + if (!!_this.pc.remoteDescription) { + _this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); }).catch(function (error) { return reject(error); }); + } + else { + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + break; + default: + _this.iceCandidateList.push(iceCandidate); + resolve(); + } + }); + }; + return WebRtcPeer; +}()); +exports.WebRtcPeer = WebRtcPeer; +var WebRtcPeerRecvonly = (function (_super) { + __extends(WebRtcPeerRecvonly, _super); + function WebRtcPeerRecvonly(configuration) { + var _this = this; + configuration.mode = 'recvonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerRecvonly; +}(WebRtcPeer)); +exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly; +var WebRtcPeerSendonly = (function (_super) { + __extends(WebRtcPeerSendonly, _super); + function WebRtcPeerSendonly(configuration) { + var _this = this; + configuration.mode = 'sendonly'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendonly; +}(WebRtcPeer)); +exports.WebRtcPeerSendonly = WebRtcPeerSendonly; +var WebRtcPeerSendrecv = (function (_super) { + __extends(WebRtcPeerSendrecv, _super); + function WebRtcPeerSendrecv(configuration) { + var _this = this; + configuration.mode = 'sendrecv'; + _this = _super.call(this, configuration) || this; + return _this; + } + return WebRtcPeerSendrecv; +}(WebRtcPeer)); +exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; + +},{"freeice":2,"platform":8,"uuid":9}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var platform = require("platform"); +var WebRtcStats = (function () { + function WebRtcStats(stream) { + this.stream = stream; + this.webRtcStatsEnabled = false; + this.statsInterval = 1; + this.stats = { + inbound: { + audio: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0 + }, + video: { + bytesReceived: 0, + packetsReceived: 0, + packetsLost: 0, + framesDecoded: 0, + nackCount: 0 + } + }, + outbound: { + audio: { + bytesSent: 0, + packetsSent: 0, + }, + video: { + bytesSent: 0, + packetsSent: 0, + framesEncoded: 0, + nackCount: 0 + } + } + }; + } + WebRtcStats.prototype.isEnabled = function () { + return this.webRtcStatsEnabled; + }; + WebRtcStats.prototype.initWebRtcStats = function () { + var _this = this; + var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); + if (!!elastestInstrumentation) { + console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + this.webRtcStatsEnabled = true; + var instrumentation_1 = JSON.parse(elastestInstrumentation); + this.statsInterval = instrumentation_1.webrtc.interval; + console.warn('localStorage item: ' + JSON.stringify(instrumentation_1)); + this.webRtcStatsIntervalId = setInterval(function () { + _this.sendStatsToHttpEndpoint(instrumentation_1); + }, this.statsInterval * 1000); + return; + } + console.debug('WebRtc stats not enabled'); + }; + WebRtcStats.prototype.stopWebRtcStats = function () { + if (this.webRtcStatsEnabled) { + clearInterval(this.webRtcStatsIntervalId); + console.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); + } + }; + WebRtcStats.prototype.getSelectedIceCandidateInfo = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.getStatsAgnostic(_this.stream.getRTCPeerConnection(), function (stats) { + if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + var localCandidateId = void 0, remoteCandidateId = void 0, googCandidatePair = void 0; + var localCandidates = {}; + var remoteCandidates = {}; + for (var key in stats) { + var stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } + else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } + else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + var finalLocalCandidate_1 = localCandidates[localCandidateId]; + if (!!finalLocalCandidate_1) { + var candList = _this.stream.getLocalIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate_1.priority) >= 0); + }); + finalLocalCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } + else { + finalLocalCandidate_1 = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + var finalRemoteCandidate_1 = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate_1) { + var candList = _this.stream.getRemoteIceCandidateList(); + var cand = candList.filter(function (c) { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate_1.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate_1.priority) >= 0); + }); + finalRemoteCandidate_1.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } + else { + finalRemoteCandidate_1 = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + resolve({ + googCandidatePair: googCandidatePair, + localCandidate: finalLocalCandidate_1, + remoteCandidate: finalRemoteCandidate_1 + }); + } + else { + reject('Selected ICE candidate info only available for Chrome'); + } + }, function (error) { + reject(error); + }); + }); + }; + WebRtcStats.prototype.sendStatsToHttpEndpoint = function (instrumentation) { + var _this = this; + var sendPost = function (json) { + var http = new XMLHttpRequest(); + var url = instrumentation.webrtc.httpEndpoint; + http.open('POST', url, true); + http.setRequestHeader('Content-type', 'application/json'); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + console.log('WebRtc stats successfully sent to ' + url + ' for stream ' + _this.stream.streamId + ' of connection ' + _this.stream.connection.connectionId); + } + }; + http.send(json); + }; + var f = function (stats) { + if (platform.name.indexOf('Firefox') !== -1) { + stats.forEach(function (stat) { + var json = {}; + if ((stat.type === 'inbound-rtp') && + (stat.nackCount !== null && + stat.isRemote === false && + stat.id.startsWith('inbound') && + stat.remoteId.startsWith('inbound'))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var jit = stat.jitter * 1000; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: jit, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.nackCount - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.nackCount; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ((stat.type === 'outbound-rtp') && + (stat.isRemote === false && + stat.id.toLowerCase().includes('outbound'))) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + }); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + for (var _i = 0, _a = Object.keys(stats); _i < _a.length; _i++) { + var key = _a[_i]; + var stat = stats[key]; + if (stat.type === 'ssrc') { + var json = {}; + if ('bytesReceived' in stat && ((stat.mediaType === 'audio' && 'audioOutputLevel' in stat) || + (stat.mediaType === 'video' && 'qpSum' in stat))) { + var metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesReceived: (stat.bytesReceived - _this.stats.inbound[stat.mediaType].bytesReceived) / _this.statsInterval, + jitter: stat.googJitterBufferMs, + packetsReceived: (stat.packetsReceived - _this.stats.inbound[stat.mediaType].packetsReceived) / _this.statsInterval, + packetsLost: (stat.packetsLost - _this.stats.inbound[stat.mediaType].packetsLost) / _this.statsInterval + }; + var units = { + bytesReceived: 'bytes', + jitter: 'ms', + packetsReceived: 'packets', + packetsLost: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesDecoded'] = (stat.framesDecoded - _this.stats.inbound.video.framesDecoded) / _this.statsInterval; + metrics['nackCount'] = (stat.googNacksSent - _this.stats.inbound.video.nackCount) / _this.statsInterval; + units['framesDecoded'] = 'frames'; + units['nackCount'] = 'packets'; + _this.stats.inbound.video.framesDecoded = stat.framesDecoded; + _this.stats.inbound.video.nackCount = stat.googNacksSent; + } + _this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived; + _this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived; + _this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + else if ('bytesSent' in stat) { + var metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc; + var metrics = { + bytesSent: (stat.bytesSent - _this.stats.outbound[stat.mediaType].bytesSent) / _this.statsInterval, + packetsSent: (stat.packetsSent - _this.stats.outbound[stat.mediaType].packetsSent) / _this.statsInterval + }; + var units = { + bytesSent: 'bytes', + packetsSent: 'packets' + }; + if (stat.mediaType === 'video') { + metrics['framesEncoded'] = (stat.framesEncoded - _this.stats.outbound.video.framesEncoded) / _this.statsInterval; + units['framesEncoded'] = 'frames'; + _this.stats.outbound.video.framesEncoded = stat.framesEncoded; + } + _this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent; + _this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent; + json = { + '@timestamp': new Date(stat.timestamp).toISOString(), + 'exec': instrumentation.exec, + 'component': instrumentation.component, + 'stream': 'webRtc', + 'et_type': metricId, + 'stream_type': 'composed_metrics', + 'units': units + }; + json[metricId] = metrics; + sendPost(JSON.stringify(json)); + } + } + } + } + }; + this.getStatsAgnostic(this.stream.getRTCPeerConnection(), f, function (error) { console.log(error); }); + }; + WebRtcStats.prototype.standardizeReport = function (response) { + console.log(response); + var standardReport = {}; + if (platform.name.indexOf('Firefox') !== -1) { + Object.keys(response).forEach(function (key) { + console.log(response[key]); + }); + return response; + } + response.result().forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + return standardReport; + }; + WebRtcStats.prototype.getStatsAgnostic = function (pc, successCb, failureCb) { + var _this = this; + if (platform.name.indexOf('Firefox') !== -1) { + return pc.getStats(null).then(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }).catch(failureCb); + } + else if ((platform.name.indexOf('Chrome') !== -1) || (platform.name.indexOf('Opera') !== -1)) { + return pc.getStats(function (response) { + var report = _this.standardizeReport(response); + successCb(report); + }, null, failureCb); + } + }; + return WebRtcStats; +}()); +exports.WebRtcStats = WebRtcStats; + +},{"platform":8}]},{},[17]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvdjEuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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RyxhQUFhLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU8sc0NBQWdCLEdBQXhCLFVBQXlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUztRQUFqRCxpQkFjQztRQWJHLElBQUksUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFFMUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7Z0JBQ2xDLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QjthQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUU5RixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBQyxRQUFRO2dCQUN4QixJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QixDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZCO0lBQ0wsQ0FBQztJQUVMLGtCQUFDO0FBQUQsQ0FyWUEsQUFxWUMsSUFBQTtBQXJZWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBub3JtYWxpY2UgPSByZXF1aXJlKCdub3JtYWxpY2UnKTtcblxuLyoqXG4gICMgZnJlZWljZVxuXG4gIFRoZSBgZnJlZWljZWAgbW9kdWxlIGlzIGEgc2ltcGxlIHdheSBvZiBnZXR0aW5nIHJhbmRvbSBTVFVOIG9yIFRVUk4gc2VydmVyXG4gIGZvciB5b3VyIFdlYlJUQyBhcHBsaWNhdGlvbi4gIFRoZSBsaXN0IG9mIHNlcnZlcnMgKGp1c3QgU1RVTiBhdCB0aGlzIHN0YWdlKVxuICB3ZXJlIHNvdXJjZWQgZnJvbSB0aGlzIFtnaXN0XShodHRwczovL2dpc3QuZ2l0aHViLmNvbS96eml1bmkvMzc0MTkzMykuXG5cbiAgIyMgRXhhbXBsZSBVc2VcblxuICBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgeW91IGNhbiB1c2UgYGZyZWVpY2VgIHdpdGhcbiAgW3J0Yy1xdWlja2Nvbm5lY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9ydGMtaW8vcnRjLXF1aWNrY29ubmVjdCk6XG5cbiAgPDw8IGV4YW1wbGVzL3F1aWNrY29ubmVjdC5qc1xuXG4gIEFzIHRoZSBgZnJlZWljZWAgbW9kdWxlIGdlbmVyYXRlcyBpY2Ugc2VydmVycyBpbiBhIGxpc3QgY29tcGxpYW50IHdpdGggdGhlXG4gIFdlYlJUQyBzcGVjIHlvdSB3aWxsIGJlIGFibGUgdG8gdXNlIGl0IHdpdGggcmF3IGBSVENQZWVyQ29ubmVjdGlvbmBcbiAgY29uc3RydWN0b3JzIGFuZCBvdGhlciBXZWJSVEMgbGlicmFyaWVzLlxuXG4gICMjIEhleSwgZG9uJ3QgdXNlIG15IFNUVU4vVFVSTiBzZXJ2ZXIhXG5cbiAgSWYgZm9yIHNvbWUgcmVhc29uIHlvdXIgZnJlZSBTVFVOIG9yIFRVUk4gc2VydmVyIGVuZHMgdXAgaW4gdGhlXG4gIGxpc3Qgb2Ygc2VydmVycyAoW3N0dW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci9zdHVuLmpzb24pIG9yXG4gIFt0dXJuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvdHVybi5qc29uKSlcbiAgdGhhdCBpcyB1c2VkIGluIHRoaXMgbW9kdWxlLCB5b3UgY2FuIGZlZWxcbiAgZnJlZSB0byBvcGVuIGFuIGlzc3VlIG9uIHRoaXMgcmVwb3NpdG9yeSBhbmQgdGhvc2Ugc2VydmVycyB3aWxsIGJlIHJlbW92ZWRcbiAgd2l0aGluIDI0IGhvdXJzIChvciBzb29uZXIpLiAgVGhpcyBpcyB0aGUgcXVpY2tlc3QgYW5kIHByb2JhYmx5IHRoZSBtb3N0XG4gIHBvbGl0ZSB3YXkgdG8gaGF2ZSBzb21ldGhpbmcgcmVtb3ZlZCAoYW5kIHByb3ZpZGVzIHVzIHNvbWUgdmlzaWJpbGl0eVxuICBpZiBzb21lb25lIG9wZW5zIGEgcHVsbCByZXF1ZXN0IHJlcXVlc3RpbmcgdGhhdCBhIHNlcnZlciBpcyBhZGRlZCkuXG5cbiAgIyMgUGxlYXNlIGFkZCBteSBzZXJ2ZXIhXG5cbiAgSWYgeW91IGhhdmUgYSBzZXJ2ZXIgdGhhdCB5b3Ugd2lzaCB0byBhZGQgdG8gdGhlIGxpc3QsIHRoYXQncyBhd2Vzb21lISBJJ21cbiAgc3VyZSBJIHNwZWFrIG9uIGJlaGFsZiBvZiBhIHdob2xlIHBpbGUgb2YgV2ViUlRDIGRldmVsb3BlcnMgd2hvIHNheSB0aGFua3MuXG4gIFRvIGdldCBpdCBpbnRvIHRoZSBsaXN0LCBmZWVsIGZyZWUgdG8gZWl0aGVyIG9wZW4gYSBwdWxsIHJlcXVlc3Qgb3IgaWYgeW91XG4gIGZpbmQgdGhhdCBwcm9jZXNzIGEgYml0IGRhdW50aW5nIHRoZW4ganVzdCBjcmVhdGUgYW4gaXNzdWUgcmVxdWVzdGluZ1xuICB0aGUgYWRkaXRpb24gb2YgdGhlIHNlcnZlciAobWFrZSBzdXJlIHlvdSBwcm92aWRlIGFsbCB0aGUgZGV0YWlscywgYW5kIGlmXG4gIHlvdSBoYXZlIGEgVGVybXMgb2YgU2VydmljZSB0aGVuIGluY2x1ZGluZyB0aGF0IGluIHRoZSBQUi9pc3N1ZSB3b3VsZCBiZVxuICBhd2Vzb21lKS5cblxuICAjIyBJIGtub3cgb2YgYSBmcmVlIHNlcnZlciwgY2FuIEkgYWRkIGl0P1xuXG4gIFN1cmUsIGlmIHlvdSBkbyB5b3VyIGhvbWV3b3JrIGFuZCBtYWtlIHN1cmUgaXQgaXMgb2sgdG8gdXNlIChJJ20gY3VycmVudGx5XG4gIGluIHRoZSBwcm9jZXNzIG9mIHJldmlld2luZyB0aGUgdGVybXMgb2YgdGhvc2UgU1RVTiBzZXJ2ZXJzIGluY2x1ZGVkIGZyb21cbiAgdGhlIG9yaWdpbmFsIGxpc3QpLiAgSWYgaXQncyBvayB0byBnbywgdGhlbiBwbGVhc2Ugc2VlIHRoZSBwcmV2aW91cyBlbnRyeVxuICBmb3IgaG93IHRvIGFkZCBpdC5cblxuICAjIyBDdXJyZW50IExpc3Qgb2YgU2VydmVyc1xuXG4gICogY3VycmVudCBhcyBhdCB0aGUgdGltZSBvZiBsYXN0IGBSRUFETUUubWRgIGZpbGUgZ2VuZXJhdGlvblxuXG4gICMjIyBTVFVOXG5cbiAgPDw8IHN0dW4uanNvblxuXG4gICMjIyBUVVJOXG5cbiAgPDw8IHR1cm4uanNvblxuXG4qKi9cblxudmFyIGZyZWVpY2UgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmcmVlaWNlOyIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIlxuXVxuIiwibW9kdWxlLmV4cG9ydHM9W11cbiIsInZhciBXaWxkRW1pdHRlciA9IHJlcXVpcmUoJ3dpbGRlbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIGdldE1heFZvbHVtZSAoYW5hbHlzZXIsIGZmdEJpbnMpIHtcbiAgdmFyIG1heFZvbHVtZSA9IC1JbmZpbml0eTtcbiAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGZmdEJpbnMpO1xuXG4gIGZvcih2YXIgaT00LCBpaT1mZnRCaW5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBpZiAoZmZ0Qmluc1tpXSA+IG1heFZvbHVtZSAmJiBmZnRCaW5zW2ldIDwgMCkge1xuICAgICAgbWF4Vm9sdW1lID0gZmZ0Qmluc1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1heFZvbHVtZTtcbn1cblxuXG52YXIgYXVkaW9Db250ZXh0VHlwZTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBhdWRpb0NvbnRleHRUeXBlID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xufVxuLy8gdXNlIGEgc2luZ2xlIGF1ZGlvIGNvbnRleHQgZHVlIHRvIGhhcmR3YXJlIGxpbWl0c1xudmFyIGF1ZGlvQ29udGV4dCA9IG51bGw7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0cmVhbSwgb3B0aW9ucykge1xuICB2YXIgaGFya2VyID0gbmV3IFdpbGRFbWl0dGVyKCk7XG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvLyBFbnN1cmUgdGhhdCBqdXN0IGEgc2luZ2xlIEF1ZGlvQ29udGV4dCBpcyBpbnRlcm5hbGx5IGNyZWF0ZWRcbiAgYXVkaW9Db250ZXh0ID0gb3B0aW9ucy5hdWRpb0NvbnRleHQgfHwgYXVkaW9Db250ZXh0IHx8IG5ldyBhdWRpb0NvbnRleHRUeXBlKCk7XG5cbiAgdmFyIHNvdXJjZU5vZGUsIGZmdEJpbnMsIGFuYWx5c2VyO1xuXG4gIGFuYWx5c2VyID0gYXVkaW9Db250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gIGFuYWx5c2VyLmZmdFNpemUgPSA1MTI7XG4gIGFuYWx5c2VyLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHNtb290aGluZztcbiAgZmZ0QmlucyA9IG5ldyBGbG9hdDMyQXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuXG4gIGlmIChzdHJlYW0uanF1ZXJ5KSBzdHJlYW0gPSBzdHJlYW1bMF07XG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBIVE1MQXVkaW9FbGVtZW50IHx8IHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAvL0F1ZGlvIFRhZ1xuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKHN0cmVhbSk7XG4gICAgaWYgKHR5cGVvZiBwbGF5ID09PSAndW5kZWZpbmVkJykgcGxheSA9IHRydWU7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfSBlbHNlIHtcbiAgICAvL1dlYlJUQyBTdHJlYW1cbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkIHx8IC01MDtcbiAgfVxuXG4gIHNvdXJjZU5vZGUuY29ubmVjdChhbmFseXNlcik7XG4gIGlmIChwbGF5KSBhbmFseXNlci5jb25uZWN0KGF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG5cbiAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG5cbiAgaGFya2VyLnN1c3BlbmQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN1c3BlbmQoKTtcbiAgfVxuICBoYXJrZXIucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5yZXN1bWUoKTtcbiAgfVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaGFya2VyLCAnc3RhdGUnLCB7IGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgfX0pO1xuICBhdWRpb0NvbnRleHQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIGhhcmtlci5lbWl0KCdzdGF0ZV9jaGFuZ2UnLCBhdWRpb0NvbnRleHQuc3RhdGUpO1xuICB9XG5cbiAgaGFya2VyLnNldFRocmVzaG9sZCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB0aHJlc2hvbGQgPSB0O1xuICB9O1xuXG4gIGhhcmtlci5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpbnRlcnZhbCA9IGk7XG4gIH07XG5cbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gICAgYW5hbHlzZXIuZGlzY29ubmVjdCgpO1xuICAgIHNvdXJjZU5vZGUuZGlzY29ubmVjdCgpO1xuICB9O1xuICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdG9yeTsgaSsrKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCk7XG4gIH1cblxuICAvLyBQb2xsIHRoZSBhbmFseXNlciBub2RlIHRvIGRldGVybWluZSBpZiBzcGVha2luZ1xuICAvLyBhbmQgZW1pdCBldmVudHMgaWYgY2hhbmdlZFxuICB2YXIgbG9vcGVyID0gZnVuY3Rpb24oKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcblxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLyohXG4gKiBQbGF0Zm9ybS5qcyA8aHR0cHM6Ly9tdGhzLmJlL3BsYXRmb3JtPlxuICogQ29weXJpZ2h0IDIwMTQtMjAxOCBCZW5qYW1pbiBUYW4gPGh0dHBzOi8vYm5qbW50NG4ubm93LnNoLz5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b24gPGh0dHA6Ly9hbGx5b3VjYW5sZWV0LmNvbS8+XG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbXRocy5iZS9taXQ+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FyY2hvcyc6IHt9LFxuICAgICAgJ0FtYXpvbic6IHsgJ0tpbmRsZSc6IDEsICdLaW5kbGUgRmlyZSc6IDEgfSxcbiAgICAgICdBc3VzJzogeyAnVHJhbnNmb3JtZXInOiAxIH0sXG4gICAgICAnQmFybmVzICYgTm9ibGUnOiB7ICdOb29rJzogMSB9LFxuICAgICAgJ0JsYWNrQmVycnknOiB7ICdQbGF5Qm9vayc6IDEgfSxcbiAgICAgICdHb29nbGUnOiB7ICdHb29nbGUgVFYnOiAxLCAnTmV4dXMnOiAxIH0sXG4gICAgICAnSFAnOiB7ICdUb3VjaFBhZCc6IDEgfSxcbiAgICAgICdIVEMnOiB7fSxcbiAgICAgICdMRyc6IHt9LFxuICAgICAgJ01pY3Jvc29mdCc6IHsgJ1hib3gnOiAxLCAnWGJveCBPbmUnOiAxIH0sXG4gICAgICAnTW90b3JvbGEnOiB7ICdYb29tJzogMSB9LFxuICAgICAgJ05pbnRlbmRvJzogeyAnV2lpIFUnOiAxLCAgJ1dpaSc6IDEgfSxcbiAgICAgICdOb2tpYSc6IHsgJ0x1bWlhJzogMSB9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgICdGZWRvcmEnLFxuICAgICAgJ0ZyZWVCU0QnLFxuICAgICAgJ0dlbnRvbycsXG4gICAgICAnSGFpa3UnLFxuICAgICAgJ0t1YnVudHUnLFxuICAgICAgJ0xpbnV4IE1pbnQnLFxuICAgICAgJ09wZW5CU0QnLFxuICAgICAgJ1JlZCBIYXQnLFxuICAgICAgJ1N1U0UnLFxuICAgICAgJ1VidW50dScsXG4gICAgICAnWHVidW50dScsXG4gICAgICAnQ3lnd2luJyxcbiAgICAgICdTeW1iaWFuIE9TJyxcbiAgICAgICdocHdPUycsXG4gICAgICAnd2ViT1MgJyxcbiAgICAgICd3ZWJPUycsXG4gICAgICAnVGFibGV0IE9TJyxcbiAgICAgICdUaXplbicsXG4gICAgICAnTGludXgnLFxuICAgICAgJ01hYyBPUyBYJyxcbiAgICAgICdNYWNpbnRvc2gnLFxuICAgICAgJ01hYycsXG4gICAgICAnV2luZG93cyA5ODsnLFxuICAgICAgJ1dpbmRvd3MgJ1xuICAgIF0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGxheW91dCBlbmdpbmUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbGF5b3V0IGVuZ2luZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMYXlvdXQoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIG1hbnVmYWN0dXJlciBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gb2JqZWN0IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgbWFudWZhY3R1cmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlcihndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgICAvLyBMb29rdXAgdGhlIG1hbnVmYWN0dXJlciBieSBwcm9kdWN0IG9yIHNjYW4gdGhlIFVBIGZvciB0aGUgbWFudWZhY3R1cmVyLlxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChcbiAgICAgICAgICB2YWx1ZVtwcm9kdWN0XSB8fFxuICAgICAgICAgIHZhbHVlWy9eW2Etel0rKD86ICtbYS16XStcXGIpKi9pLmV4ZWMocHJvZHVjdCldIHx8XG4gICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBxdWFsaWZ5KGtleSkgKyAnKD86XFxcXGJ8XFxcXHcqXFxcXGQpJywgJ2knKS5leGVjKHVhKVxuICAgICAgICApICYmIGtleTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBicm93c2VyIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgYnJvd3NlciBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hbWUoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgUmVnRXhwKCdcXFxcYicgKyAoXG4gICAgICAgICAgZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKVxuICAgICAgICApICsgJ1xcXFxiJywgJ2knKS5leGVjKHVhKSAmJiAoZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIE9TIG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgT1MgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPUyhndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/Oi9bXFxcXGQuXSt8WyBcXFxcdy5dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gY2xlYW51cE9TKHJlc3VsdCwgcGF0dGVybiwgZ3Vlc3MubGFiZWwgfHwgZ3Vlc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgcHJvZHVjdCBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHByb2R1Y3QgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRQcm9kdWN0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcZCtbLlxcXFx3X10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnICpcXFxcdystW1xcXFx3XSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzo7ICooPzpbYS16XStbXy1dKT9bYS16XStcXFxcZCt8W14gKCk7LV0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAvLyBTcGxpdCBieSBmb3J3YXJkIHNsYXNoIGFuZCBhcHBlbmQgcHJvZHVjdCB2ZXJzaW9uIGlmIG5lZWRlZC5cbiAgICAgICAgICBpZiAoKHJlc3VsdCA9IFN0cmluZygoZ3Vlc3MubGFiZWwgJiYgIVJlZ0V4cChwYXR0ZXJuLCAnaScpLnRlc3QoZ3Vlc3MubGFiZWwpKSA/IGd1ZXNzLmxhYmVsIDogcmVzdWx0KS5zcGxpdCgnLycpKVsxXSAmJiAhL1tcXGQuXSsvLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgICAgcmVzdWx0WzBdICs9ICcgJyArIHJlc3VsdFsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29ycmVjdCBjaGFyYWN0ZXIgY2FzZSBhbmQgY2xlYW51cCBzdHJpbmcuXG4gICAgICAgICAgZ3Vlc3MgPSBndWVzcy5sYWJlbCB8fCBndWVzcztcbiAgICAgICAgICByZXN1bHQgPSBmb3JtYXQocmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAocGF0dGVybiwgJ2knKSwgZ3Vlc3MpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJzsgKig/OicgKyBndWVzcyArICdbXy1dKT8nLCAnaScpLCAnICcpXG4gICAgICAgICAgICAucmVwbGFjZShSZWdFeHAoJygnICsgZ3Vlc3MgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCAnJDEgJDInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSB2ZXJzaW9uIHVzaW5nIGFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXR0ZXJucyBBbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZlcnNpb24ocGF0dGVybnMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UocGF0dGVybnMsIGZ1bmN0aW9uKHJlc3VsdCwgcGF0dGVybikge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IChSZWdFeHAocGF0dGVybiArXG4gICAgICAgICAgJyg/Oi1bXFxcXGQuXSsvfCg/OiBmb3IgW1xcXFx3LV0rKT9bIC8tXSkoW1xcXFxkLl0rW14gKCk7L18tXSopJywgJ2knKS5leGVjKHVhKSB8fCAwKVsxXSB8fCBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIHdoZW4gdGhlIHBsYXRmb3JtIG9iamVjdCBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgaWYgYXZhaWxhYmxlLCBlbHNlIGFuIGVtcHR5IHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZ1BsYXRmb3JtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQ29udmVydCBsYXlvdXQgdG8gYW4gYXJyYXkgc28gd2UgY2FuIGFkZCBleHRyYSBkZXRhaWxzLlxuICAgIGxheW91dCAmJiAobGF5b3V0ID0gW2xheW91dF0pO1xuXG4gICAgLy8gRGV0ZWN0IHByb2R1Y3QgbmFtZXMgdGhhdCBjb250YWluIHRoZWlyIG1hbnVmYWN0dXJlcidzIG5hbWUuXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiAhcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IGdldFByb2R1Y3QoW21hbnVmYWN0dXJlcl0pO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAhL2J1bnR1L2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEZ4aU9TfElFTW9iaWxlfElyb258T3BlcmEgP01pbml8T1BpT1N8T1BSfFJhdmVufFNhbXN1bmdCcm93c2VyfFNpbGsoPyEvW1xcXFxkLl0rJCkpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKS9pLmV4ZWModWEpIHx8IDApWzFdO1xuICAgICAgLy8gRGV0ZWN0IEJsaW5rIGxheW91dCBlbmdpbmUuXG4gICAgICBpZiAoZGF0YVswXSA9PSA1MzcuMzYgJiYgZGF0YVsyXSA9PSA1MzcuMzYgJiYgcGFyc2VGbG9hdChkYXRhWzFdKSA+PSAyOCAmJiBsYXlvdXQgPT0gJ1dlYktpdCcpIHtcbiAgICAgICAgbGF5b3V0ID0gWydCbGluayddO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEphdmFTY3JpcHRDb3JlLlxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NzY4NDc0L2hvdy1jYW4taS1kZXRlY3Qtd2hpY2gtamF2YXNjcmlwdC1lbmdpbmUtdjgtb3ItanNjLWlzLXVzZWQtYXQtcnVudGltZS1pbi1hbmRyb2lcbiAgICAgIGlmICghdXNlRmVhdHVyZXMgfHwgKCFsaWtlQ2hyb21lICYmICFkYXRhWzFdKSkge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIFNhZmFyaScpO1xuICAgICAgICBkYXRhID0gKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNDAwID8gMSA6IGRhdGEgPCA1MDAgPyAyIDogZGF0YSA8IDUyNiA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQgPyAnNCsnIDogZGF0YSA8IDUzNSA/IDUgOiBkYXRhIDwgNTM3ID8gNiA6IGRhdGEgPCA1MzggPyA3IDogZGF0YSA8IDYwMSA/IDggOiAnOCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBDaHJvbWUnKTtcbiAgICAgICAgZGF0YSA9IGRhdGFbMV0gfHwgKGRhdGEgPSBkYXRhWzBdLCBkYXRhIDwgNTMwID8gMSA6IGRhdGEgPCA1MzIgPyAyIDogZGF0YSA8IDUzMi4wNSA/IDMgOiBkYXRhIDwgNTMzID8gNCA6IGRhdGEgPCA1MzQuMDMgPyA1IDogZGF0YSA8IDUzNC4wNyA/IDYgOiBkYXRhIDwgNTM0LjEwID8gNyA6IGRhdGEgPCA1MzQuMTMgPyA4IDogZGF0YSA8IDUzNC4xNiA/IDkgOiBkYXRhIDwgNTM0LjI0ID8gMTAgOiBkYXRhIDwgNTM0LjMwID8gMTEgOiBkYXRhIDwgNTM1LjAxID8gMTIgOiBkYXRhIDwgNTM1LjAyID8gJzEzKycgOiBkYXRhIDwgNTM1LjA3ID8gMTUgOiBkYXRhIDwgNTM1LjExID8gMTYgOiBkYXRhIDwgNTM1LjE5ID8gMTcgOiBkYXRhIDwgNTM2LjA1ID8gMTggOiBkYXRhIDwgNTM2LjEwID8gMTkgOiBkYXRhIDwgNTM3LjAxID8gMjAgOiBkYXRhIDwgNTM3LjExID8gJzIxKycgOiBkYXRhIDwgNTM3LjEzID8gMjMgOiBkYXRhIDwgNTM3LjE4ID8gMjQgOiBkYXRhIDwgNTM3LjI0ID8gMjUgOiBkYXRhIDwgNTM3LjM2ID8gMjYgOiBsYXlvdXQgIT0gJ0JsaW5rJyA/ICcyNycgOiAnMjgnKTtcbiAgICAgIH1cbiAgICAgIC8vIEFkZCB0aGUgcG9zdGZpeCBvZiBcIi54XCIgb3IgXCIrXCIgZm9yIGFwcHJveGltYXRlIHZlcnNpb25zLlxuICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gKz0gJyAnICsgKGRhdGEgKz0gdHlwZW9mIGRhdGEgPT0gJ251bWJlcicgPyAnLngnIDogL1suK10vLnRlc3QoZGF0YSkgPyAnJyA6ICcrJykpO1xuICAgICAgLy8gT2JzY3VyZSB2ZXJzaW9uIGZvciBzb21lIFNhZmFyaSAxLTIgcmVsZWFzZXMuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAoIXZlcnNpb24gfHwgcGFyc2VJbnQodmVyc2lvbikgPiA0NSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IGRhdGE7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFN0cmlwIGluY29ycmVjdCBPUyB2ZXJzaW9ucy5cbiAgICBpZiAodmVyc2lvbiAmJiB2ZXJzaW9uLmluZGV4T2YoKGRhdGEgPSAvW1xcZC5dKyQvLmV4ZWMob3MpKSkgPT0gMCAmJlxuICAgICAgICB1YS5pbmRleE9mKCcvJyArIGRhdGEgKyAnLScpID4gLTEpIHtcbiAgICAgIG9zID0gdHJpbShvcy5yZXBsYWNlKGRhdGEsICcnKSk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJVYnVudHVcIiwgXCJEZWJpYW5cIiwgXCJGZWRvcmFcIiwgXCJSZWQgSGF0XCIsIFwiU3VTRVwiLFxuICAgICAgICogXCJBbmRyb2lkXCIsIFwiaU9TXCIgYW5kIFwiV2luZG93cyBQaG9uZVwiXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAnZmFtaWx5JzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAgICovXG4gICAgICAndmVyc2lvbic6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgT1Mgc3RyaW5nLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIE9TIHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgJ3RvU3RyaW5nJzogZnVuY3Rpb24oKSB7IHJldHVybiAnbnVsbCc7IH1cbiAgICB9O1xuXG4gICAgcGxhdGZvcm0ucGFyc2UgPSBwYXJzZTtcbiAgICBwbGF0Zm9ybS50b1N0cmluZyA9IHRvU3RyaW5nUGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0udmVyc2lvbikge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCh2ZXJzaW9uKTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtLm5hbWUpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQobmFtZSk7XG4gICAgfVxuICAgIGlmIChvcyAmJiBuYW1lICYmICEob3MgPT0gU3RyaW5nKG9zKS5zcGxpdCgnICcpWzBdICYmIChvcyA9PSBuYW1lLnNwbGl0KCcgJylbMF0gfHwgcHJvZHVjdCkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKHByb2R1Y3QgPyAnKCcgKyBvcyArICcpJyA6ICdvbiAnICsgb3MpO1xuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoKSB7XG4gICAgICBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYXRmb3JtO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IHBsYXRmb3JtLlxuICB2YXIgcGxhdGZvcm0gPSBwYXJzZSgpO1xuXG4gIC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBwbGF0Zm9ybSBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIHBsYXRmb3JtIGlzXG4gICAgLy8gbG9hZGVkIGJ5IGEgc2NyaXB0IHRhZyBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EIGxvYWRlci5cbiAgICAvLyBTZWUgaHR0cDovL3JlcXVpcmVqcy5vcmcvZG9jcy9lcnJvcnMuaHRtbCNtaXNtYXRjaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuICAgIC8vIERlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHNvIHBsYXRmb3JtIGNhbiBiZSBhbGlhc2VkIHRocm91Z2ggcGF0aCBtYXBwaW5nLlxuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBhbiBgZXhwb3J0c2Agb2JqZWN0LlxuICBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZvck93bihwbGF0Zm9ybSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgZnJlZUV4cG9ydHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCBcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gdGhlXG4vLyBicm93c2VyIHRoaXMgaXMgYSBsaXR0bGUgY29tcGxpY2F0ZWQgZHVlIHRvIHVua25vd24gcXVhbGl0eSBvZiBNYXRoLnJhbmRvbSgpXG4vLyBhbmQgaW5jb25zaXN0ZW50IHN1cHBvcnQgZm9yIHRoZSBgY3J5cHRvYCBBUEkuICBXZSBkbyB0aGUgYmVzdCB3ZSBjYW4gdmlhXG4vLyBmZWF0dXJlLWRldGVjdGlvblxuXG4vLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG9cbi8vIGltcGxlbWVudGF0aW9uLiBBbHNvLCBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gb24gSUUxMS5cbnZhciBnZXRSYW5kb21WYWx1ZXMgPSAodHlwZW9mKGNyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mKG1zQ3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKSk7XG5cbmlmIChnZXRSYW5kb21WYWx1ZXMpIHtcbiAgLy8gV0hBVFdHIGNyeXB0byBSTkcgLSBodHRwOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3J5cHRvXG4gIHZhciBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG4gICAgcmV0dXJuIHJuZHM4O1xuICB9O1xufSBlbHNlIHtcbiAgLy8gTWF0aC5yYW5kb20oKS1iYXNlZCAoUk5HKVxuICAvL1xuICAvLyBJZiBhbGwgZWxzZSBmYWlscywgdXNlIE1hdGgucmFuZG9tKCkuICBJdCdzIGZhc3QsIGJ1dCBpcyBvZiB1bnNwZWNpZmllZFxuICAvLyBxdWFsaXR5LlxuICB2YXIgcm5kcyA9IG5ldyBBcnJheSgxNik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRoUk5HKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBybmRzW2ldID0gciA+Pj4gKChpICYgMHgwMykgPDwgMykgJiAweGZmO1xuICAgIH1cblxuICAgIHJldHVybiBybmRzO1xuICB9O1xufVxuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIHZhciBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7XG5cbiAgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIHZhciBzZWVkQnl0ZXMgPSBybmcoKTtcbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW1xuICAgICAgICBzZWVkQnl0ZXNbMF0gfCAweDAxLFxuICAgICAgICBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XVxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9XG5cbiAgLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG4gIHZhciBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG4gIHZhciBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTtcblxuICAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG4gIHZhciBkdCA9IChtc2VjcyAtIF9sYXN0TVNlY3MpICsgKG5zZWNzIC0gX2xhc3ROU2VjcykvMTAwMDA7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9XG5cbiAgLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfVxuXG4gIC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1dWlkLnYxKCk6IENhblxcJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjJyk7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7XG5cbiAgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwO1xuXG4gIC8vIGB0aW1lX2xvd2BcbiAgdmFyIHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjtcblxuICAvLyBgdGltZV9taWRgXG4gIHZhciB0bWggPSAobXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwKSAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjtcblxuICAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmO1xuXG4gIC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7XG5cbiAgLy8gYGNsb2NrX3NlcV9sb3dgXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjtcblxuICAvLyBgbm9kZWBcbiAgZm9yICh2YXIgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmID8gYnVmIDogYnl0ZXNUb1V1aWQoYik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjE7XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi42IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIixcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxMi42LjhcIixcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuMlwiLFxuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjVcIixcbiAgICAgICAgXCJ1dWlkXCI6IFwiMy4zLjJcIixcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi42XCJcbiAgICB9LFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNi4zLjBcIixcbiAgICAgICAgXCJncnVudFwiOiBcIjEuMC40XCIsXG4gICAgICAgIFwiZ3J1bnQtYXV0b3ByZWZpeGVyXCI6IFwiMy4wLjRcIixcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjMuMlwiLFxuICAgICAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIjEuMC4wXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMS4wLjBcIixcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjQuMC4xXCIsXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi13YXRjaFwiOiBcIjEuMS4wXCIsXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuMVwiLFxuICAgICAgICBcImdydW50LXRzXCI6IFwiNi4wLjAtYmV0YS4yMlwiLFxuICAgICAgICBcInRzaWZ5XCI6IFwiNC4wLjFcIixcbiAgICAgICAgXCJ0c2xpbnRcIjogXCI1LjE4LjBcIixcbiAgICAgICAgXCJ0eXBlZG9jXCI6IFwiMC4xNS4wXCIsXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjMuNS4zXCIsXG4gICAgICAgIFwidWdsaWZ5LWpzXCI6IFwiMy42LjBcIlxuICAgIH0sXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICAgIFwibmFtZVwiOiBcIm9wZW52aWR1LWJyb3dzZXJcIixcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LFxuICAgIFwic2NyaXB0c1wiOiB7XG4gICAgICAgIFwiYnJvd3NlcmlmeVwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLFxuICAgICAgICBcImJyb3dzZXJpZnktcHJvZFwiOiBcIlZFUlNJT049JHtWRVJTSU9OOi19OyBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy91Z2xpZnktanMvYmluL3VnbGlmeWpzIC0tc291cmNlLW1hcCBjb250ZW50PWlubGluZSAtLW91dHB1dCAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5taW4uanNcIixcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdFwiLFxuICAgICAgICBcImRvY3NcIjogXCIuL25vZGVfbW9kdWxlcy90eXBlZG9jL2Jpbi90eXBlZG9jIC0tb3B0aW9ucyAuL2NvbmZpZy90eXBlZG9jLmpzIC0tb3V0IC4vZG9jcyAuL3NyYyAmJiBybSAtcmYgLi4vLi4vb3BlbnZpZHUuaW8vYXBpL29wZW52aWR1LWJyb3dzZXIvKiAmJiBjcCAtUiAuL2RvY3MvLiAuLi8uLi9vcGVudmlkdS5pby9hcGkvb3BlbnZpZHUtYnJvd3NlclwiLFxuICAgICAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gICAgfSxcbiAgICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgICBcInZlcnNpb25cIjogXCIyLjExLjBcIlxufVxuIiwiaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1L09wZW5WaWR1JztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0Nvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuXG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgb3B0cz86IENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISFvcHRzKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgbXNnICs9IFwiKHJlbW90ZSkgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyBvcHRzLmlkICsgJ10nO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cztcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gb3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gb3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAob3B0cy5tZXRhZGF0YSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG9wdHMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyhvcHRzLnN0cmVhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBsb2NhbFxuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8obXNnKTtcbiAgICB9XG5cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoKCEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsJyA6ICdSZW1vdGUnKSArICdjYW5kaWRhdGUgZm9yJyArXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ29uSWNlQ2FuZGlkYXRlJywge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJ1xuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0UmVtb3RlU3RyZWFtcyhvcHRpb25zOiBTdHJlYW1PcHRpb25zU2VydmVyW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IG9wdHMuaWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBvcHRzLmNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiBvcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiBvcHRzLmhhc1ZpZGVvLFxuICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiBvcHRzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBvcHRzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiBvcHRzLnR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogb3B0cy5mcmFtZVJhdGUsXG4gICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiAhIW9wdHMudmlkZW9EaW1lbnNpb25zID8gSlNPTi5wYXJzZShvcHRzLnZpZGVvRGltZW5zaW9ucykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiAhIW9wdHMuZmlsdGVyID8gb3B0cy5maWx0ZXIgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgU3RyZWFtKHRoaXMuc2Vzc2lvbiwgc3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkU3RyZWFtKHN0cmVhbSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsIHRoaXMuc3RyZWFtLmluYm91bmRTdHJlYW1PcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuXG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSBbW0ZpbHRlci5leGVjTWV0aG9kXV0gd2FzIGNhbGxlZC4gSWYgYHVuZGVmaW5lZGAgdGhpcyBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIHZhbHVlIHRvIGtub3cgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIGFueSBhcHBsaWVkIGZpbHRlclxuICAgICAqL1xuICAgIGxhc3RFeGVjTWV0aG9kPzoge1xuICAgICAgICBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBPYmplY3RcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBPYmpNYXA8KGV2ZW50OiBGaWx0ZXJFdmVudCkgPT4gdm9pZD4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSA8c3RyaW5nPnBhcmFtcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIG1ldGhvZCBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0geyBtZXRob2QsIHBhcmFtczogSlNPTi5wYXJzZShzdHJpbmdQYXJhbXMpIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbS5zZXNzaW9uLCB0aGlzLnN0cmVhbSwgJ2ZpbHRlcicsIHRoaXMuc3RyZWFtLmZpbHRlciwgb2xkVmFsdWUsICdleGVjRmlsdGVyTWV0aG9kJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHRoaXMuc3RyZWFtLCAnZmlsdGVyJywgdGhpcy5zdHJlYW0uZmlsdGVyLCBvbGRWYWx1ZSwgJ2V4ZWNGaWx0ZXJNZXRob2QnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50VHlwZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaGFuZGxlcnNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5kZWNsYXJlIHZhciBNZWRpYVJlY29yZGVyOiBhbnk7XG5cblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICpcbiAqID4gV0FSTklOR1M6XG4gKiAtIFBlcmZvcm1pbmcgYnJvd3NlciBsb2NhbCByZWNvcmRpbmcgb2YgKipyZW1vdGUgc3RyZWFtcyoqIG1heSBjYXVzZSBzb21lIHRyb3VibGVzLiBBIGxvbmcgd2FpdGluZyB0aW1lIG1heSBiZSByZXF1aXJlZCBhZnRlciBjYWxsaW5nIF9Mb2NhbFJlY29yZGVyLnN0b3AoKV8gaW4gdGhpcyBjYXNlXG4gKiAtIE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IHN1cHBvcnQgbG9jYWwgc3RyZWFtIHJlY29yZGluZ1xuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG5cbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IGFueTtcbiAgICBwcml2YXRlIGNodW5rczogYW55W10gPSBbXTtcbiAgICBwcml2YXRlIGJsb2I6IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICghIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24pID8gdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgOiAnZGVmYXVsdC1jb25uZWN0aW9uJztcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ18nICsgdGhpcy5jb25uZWN0aW9uSWQgKyAnX2xvY2FscmVjb3JkJztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhUmVjb3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGJyb3dzZXIuIFNlZSBjb21wYXRpYmlsaXR5IGluIGh0dHBzOi8vY2FuaXVzZS5jb20vI3NlYXJjaD1NZWRpYVJlY29yZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgYnJvd3Nlci4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZWNvcmQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUFEWVxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLmNsZWFuKClcXCcgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlci5pc1R5cGVTdXBwb3J0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA5JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA5JyB9O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE1lZGlhUmVjb3JkZXIuaXNUeXBlU3VwcG9ydGVkKCd2aWRlby93ZWJtO2NvZGVjcz1oMjY0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9aDI2NCcgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNZWRpYVJlY29yZGVyLmlzVHlwZVN1cHBvcnRlZCgndmlkZW8vd2VibTtjb2RlY3M9dnA4JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibTtjb2RlY3M9dnA4JyB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2luZyBtaW1lVHlwZSAnICsgb3B0aW9ucy5taW1lVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignaXNUeXBlU3VwcG9ydGVkIGlzIG5vdCBzdXBwb3J0ZWQsIHVzaW5nIGRlZmF1bHQgY29kZWNzIGZvciBicm93c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgxMCk7XG5cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBzdGFydGVkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25wYXVzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ud2FybmluZyA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgd2FybmluZzogJyArIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuc3RvcCgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ1JFQ09SRElOR1xcJyBvciBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQucGF1c2UoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdSRUNPUkRJTkdcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdGFydCgpXFwnIG9yIFxcJ0xvY2FsUmVjb3JkZXIucmVzdW1lKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5yZXN1bWUoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdQQVVTRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5wYXVzZSgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnJlc3VtZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVDT1JESU5HO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdcXCdMb2NhbFJlY29yZC5wcmV2aWV3KClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJykge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIFtbc3RhdGVdXSB0byBgUkVBRFlgIHNvIHRoZSByZWNvcmRpbmcgY2FuIHN0YXJ0IGFnYWluXG4gICAgICovXG4gICAgY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGYgPSAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ibG9iO1xuICAgICAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhUmVjb3JkZXI7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKS50aGVuKCgpID0+IGYoKSkuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyB0aHJvdWdoIHRoZSBicm93c2VyLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZG93bmxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IChFcnJvcignXFwnTG9jYWxSZWNvcmQuZG93bmxvYWQoKVxcJyBuZWVkcyBcXCdMb2NhbFJlY29yZC5zdGF0ZVxcJyB0byBiZSBcXCdGSU5JU0hFRFxcJyAoY3VycmVudCB2YWx1ZTogXFwnJyArIHRoaXMuc3RhdGUgKyAnXFwnKS4gQ2FsbCBcXCdMb2NhbFJlY29yZGVyLnN0b3AoKVxcJyBiZWZvcmUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcud2VibSc7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcmF3IEJsb2IgZmlsZS4gTWV0aG9kcyBwcmV2aWV3LCBkb3dubG9hZCwgdXBsb2FkQXNCaW5hcnkgYW5kIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSB1c2UgdGhpcyBzYW1lIGZpbGUgdG8gcGVyZm9ybSB0aGVpciBzcGVjaWZpYyBhY3Rpb25zLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgKEVycm9yKCdDYWxsIFxcJ0xvY2FsUmVjb3JkLnN0b3AoKVxcJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGUnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdcXCdMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpXFwnIG5lZWRzIFxcJ0xvY2FsUmVjb3JkLnN0YXRlXFwnIHRvIGJlIFxcJ0ZJTklTSEVEXFwnIChjdXJyZW50IHZhbHVlOiBcXCcnICsgdGhpcy5zdGF0ZSArICdcXCcpLiBDYWxsIFxcJ0xvY2FsUmVjb3JkZXIuc3RvcCgpXFwnIGJlZm9yZScpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgbXVsdGlwYXJ0IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3Q6XG4gICAgICovXG4gICAgdXBsb2FkQXNNdWx0aXBhcnRmaWxlKGVuZHBvaW50OiBzdHJpbmcsIGhlYWRlcnM/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignXFwnTG9jYWxSZWNvcmQudXBsb2FkQXNNdWx0aXBhcnRmaWxlKClcXCcgbmVlZHMgXFwnTG9jYWxSZWNvcmQuc3RhdGVcXCcgdG8gYmUgXFwnRklOSVNIRURcXCcgKGN1cnJlbnQgdmFsdWU6IFxcJycgKyB0aGlzLnN0YXRlICsgJ1xcJykuIENhbGwgXFwnTG9jYWxSZWNvcmRlci5zdG9wKClcXCcgYmVmb3JlJykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iLCB0aGlzLmlkICsgJy53ZWJtJyk7XG5cbiAgICAgICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh0dHAuc3RhdHVzLnRvU3RyaW5nKCkuY2hhckF0KDApID09PSAnMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHJlc3BvbnNlIGZyb20gc2VydmVyIChIVFRQIHN0YXR1cyBzdGFuZGFyZDogMlhYIGlzIHN1Y2Nlc3MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgb25TdG9wRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6ICd2aWRlby93ZWJtJyB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHRoaXMuYmxvYik7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRDtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgTG9jYWxSZWNvcmRlciB9IGZyb20gJy4vTG9jYWxSZWNvcmRlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nQXV0byBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy1BdXRvJztcbmltcG9ydCAqIGFzIHNjcmVlblNoYXJpbmcgZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmcnO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xucGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSA9IChwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBob25lJyB8fCBwbGF0Zm9ybS5wcm9kdWN0ID09PSAnaVBhZCcpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xucGxhdGZvcm1bJ2lzSW9uaWNBbmRyb2lkJ10gPSBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gXCJBbmRyb2lkIEJyb3dzZXJcIjtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZXNzaW9uOiBTZXNzaW9uO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgcHVibGlzaGVyczogUHVibGlzaGVyW10gPSBbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBodHRwVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzZWNyZXQgPSAnJztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJlY29yZGVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHJvbGU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcblxuICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc29sZS5pbmZvKFwib3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiBcIiArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnKSB7XG4gICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgKDxhbnk+d2luZG93KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2gocHVibGlzaGVyID0+IHtcbiAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8gJiYgISFwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdKSB7XG5cbiAgICAgICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IG9sZFdpZHRoID0gcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBvbGRIZWlnaHQgPSBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE5ld1ZpZGVvRGltZW5zaW9ucyA9ICgpOiBQcm9taXNlPHsgbmV3V2lkdGg6IG51bWJlciwgbmV3SGVpZ2h0OiBudW1iZXIgfT4gPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExpbWl0YXRpb246IG11c3QgZ2V0IG5ldyBkaW1lbnNpb25zIGZyb20gYW4gZXhpc3RpbmcgdmlkZW8gZWxlbWVudCBhbHJlYWR5IGluc2VydGVkIGludG8gRE9NXG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGg6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtTWFuYWdlci52aWRlb3NbMF0udmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0OiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgIC8vIE5ldyByZXNvbHV0aW9uIGdvdCBmcm9tIGRpZmZlcmVudCBwbGFjZXMgZm9yIENocm9tZSBhbmQgRmlyZWZveC4gQ2hyb21lIG5lZWRzIGEgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHQgb2YgYSB2aWRlb0VsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIGdldFNldHRpbmdzIGZyb20gdGhlIHZpZGVvVHJhY2tcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IHB1Ymxpc2hlci5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy53aWR0aCA6IHB1Ymxpc2hlci52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IDxudW1iZXI+KChwbGF0Zm9ybS5uYW1lISEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA/IGZpcmVmb3hTZXR0aW5ncy5oZWlnaHQgOiBwdWJsaXNoZXIudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7IG5ld1dpZHRoLCBuZXdIZWlnaHQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICBnZXROZXdWaWRlb0RpbWVuc2lvbnMoKS50aGVuKG5ld0RpbWVuc2lvbnMgPT4ge1xuICAgICAgICAgICAgICAgIHNlbmRTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChvbGRXaWR0aCwgb2xkSGVpZ2h0LCBuZXdEaW1lbnNpb25zLm5ld1dpZHRoLCBuZXdEaW1lbnNpb25zLm5ld0hlaWdodCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgNzUpO1xuXG4gICAgICAgICAgICBjb25zdCBzZW5kU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgPSAob2xkV2lkdGgsIG9sZEhlaWdodCwgbmV3V2lkdGgsIG5ld0hlaWdodCkgPT4ge1xuICAgICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgICBpZiAoYXR0ZW1wdHMgPiAxMCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdIZWlnaHQgIT09IG9sZEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeShwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ2RldmljZVJvdGF0ZWQnXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgeyB3aWR0aDogb2xkV2lkdGgsIGhlaWdodDogb2xkSGVpZ2h0IH0sICdkZXZpY2VSb3RhdGVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLCB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSwgJ2RldmljZVJvdGF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVwZWF0VW50aWxDaGFuZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG5ldyBzZXNzaW9uXG4gICAqL1xuICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uO1xuICB9XG5cblxuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFB1Ymxpc2hlcjtcbiAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAqXG4gICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICpcbiAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBgYWNjZXNzRGVuaWVkYCBldmVudCBvbmNlIGl0IGhhcyBiZWVuIGdyYW50ZWQgYWNjZXNzIHRvIHRoZSByZXF1ZXN0ZWQgaW5wdXQgZGV2aWNlcyBvciBub3QuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50ICBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICovXG4gIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuXG4gICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICBpZiAoISFwYXJhbTIgJiYgKHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpKSB7XG5cbiAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgcHJvcGVydGllcyA9ICg8UHVibGlzaGVyUHJvcGVydGllcz5wYXJhbTIpO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBhdWRpb1NvdXJjZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICBmcmFtZVJhdGU6ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spID8gdW5kZWZpbmVkIDogKCh0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMuZnJhbWVSYXRlIDogdW5kZWZpbmVkKSxcbiAgICAgICAgaW5zZXJ0TW9kZTogKHR5cGVvZiBwcm9wZXJ0aWVzLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnKSA/ICgodHlwZW9mIHByb3BlcnRpZXMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV0gOiBwcm9wZXJ0aWVzLmluc2VydE1vZGUpIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgbWlycm9yOiAodHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJykgPyBwcm9wZXJ0aWVzLm1pcnJvciA6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogKHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcpID8gcHJvcGVydGllcy5wdWJsaXNoQXVkaW8gOiB0cnVlLFxuICAgICAgICBwdWJsaXNoVmlkZW86ICh0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucHVibGlzaFZpZGVvIDogdHJ1ZSxcbiAgICAgICAgcmVzb2x1dGlvbjogKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyB1bmRlZmluZWQgOiAoKHR5cGVvZiBwcm9wZXJ0aWVzLnJlc29sdXRpb24gIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMucmVzb2x1dGlvbiA6ICc2NDB4NDgwJyksXG4gICAgICAgIHZpZGVvU291cmNlOiAodHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnKSA/IHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgOiB1bmRlZmluZWQsXG4gICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgcHVibGlzaFZpZGVvOiB0cnVlLFxuICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgIGlmICghIXBhcmFtMiAmJiAodHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgIH1cblxuICAgIHB1Ymxpc2hlci5pbml0aWFsaXplKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgcmV0dXJuIHB1Ymxpc2hlcjtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICpcbiAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgKi9cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICovXG4gIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICovXG4gIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG4gICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgIC8vIFJlamVjdCBpUGhvbmVzIGFuZCBpUGFkcyBpZiBub3QgU2FmYXJpICgnU2FmYXJpJyBhbHNvIGNvdmVycyBJb25pYyBmb3IgaU9TKVxuICAgIGlmIChmYW1pbHkgPT09ICdpT1MnICYmIChicm93c2VyICE9PSAnU2FmYXJpJyB8fCB1c2VyQWdlbnQuaW5kZXhPZignQ3JpT1MnKSAhPT0gLTEgfHwgdXNlckFnZW50LmluZGV4T2YoJ0Z4aU9TJykgIT09IC0xKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gQWNjZXB0OiBDaHJvbWUgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLCBGaXJlZm94IChkZXNrdG9wIGFuZCBBbmRyb2lkKSwgT3BlcmEgKGRlc2t0b3AgYW5kIEFuZHJvaWQpLFxuICAgIC8vIFNhZmFyaSAoT1NYIGFuZCBpT1MpLCBJb25pYyAoQW5kcm9pZCBhbmQgaU9TKVxuICAgIGlmIChcbiAgICAgIChicm93c2VyICE9PSAnU2FmYXJpJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdDaHJvbWUgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnRmlyZWZveCcpICYmIChicm93c2VyICE9PSAnRmlyZWZveCBNb2JpbGUnKSAmJlxuICAgICAgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnT3BlcmEgTW9iaWxlJykgJiZcbiAgICAgIChicm93c2VyICE9PSAnQW5kcm9pZCBCcm93c2VyJykgJiYgKGJyb3dzZXIgIT09ICdFbGVjdHJvbicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgKi9cbiAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IG51bWJlciB7XG4gICAgY29uc3QgYnJvd3NlciA9IHBsYXRmb3JtLm5hbWU7XG4gICAgY29uc3QgZmFtaWx5ID0gcGxhdGZvcm0ub3MhIS5mYW1pbHk7XG5cbiAgICAvLyBSZWplY3QgbW9iaWxlIGRldmljZXNcbiAgICBpZiAoZmFtaWx5ID09PSAnaU9TJyB8fCBmYW1pbHkgPT09ICdBbmRyb2lkJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKChicm93c2VyICE9PSAnQ2hyb21lJykgJiYgKGJyb3dzZXIgIT09ICdGaXJlZm94JykgJiYgKGJyb3dzZXIgIT09ICdPcGVyYScpICYmIChicm93c2VyICE9PSAnRWxlY3Ryb24nKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgKi9cbiAgZ2V0RGV2aWNlcygpOiBQcm9taXNlPERldmljZVtdPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljQW5kcm9pZCddICYmIGNvcmRvdmEucGx1Z2lucyAmJiBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgIGNvcmRvdmEucGx1Z2lucy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luLmdldEVudW1lcmF0ZURldmljZXMoKS50aGVuKChwbHVnaW5EZXZpY2VzOiBEZXZpY2VbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICBsZXQgYXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpO1xuICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IERldmljZSkgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0Jyk7XG4gICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJGcm9udCBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IFwiQmFjayBDYW1lcmFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSBcIlVua25vd24gQ2FtZXJhXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gXCJcIjtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsID0gXCJVbmtub3duIE1pY3JvcGhvbmVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKGRldmljZUluZm8gPT4ge1xuICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgKlxuICAgKiBQYXJhbWV0ZXIgYG9wdGlvbnNgIGlzIHRoZSBzYW1lIGFzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0pLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2lsbCBiZSBhcHBsaWVkOiBgYXVkaW9Tb3VyY2VgLCBgdmlkZW9Tb3VyY2VgLCBgZnJhbWVSYXRlYCwgYHJlc29sdXRpb25gXG4gICAqXG4gICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgKiBgYGBcbiAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAqXG4gICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZTtcbiAgICogICAgdmlkZW9Tb3VyY2U6IHVuZGVmaW5lZCxcbiAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAqIH0pXG4gICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICpcbiAgICogICAgdmFyIHZpZGVvVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICpcbiAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAqICAgIGN0eC5maWx0ZXIgPSAnZ3JheXNjYWxlKDEwMCUpJztcbiAgICpcbiAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICogICAgICB2YXIgbG9vcCA9ICgpID0+IHtcbiAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAqICAgICAgICAgIHNldFRpbWVvdXQobG9vcCwgMTAwMC8gRlJBTUVfUkFURSk7IC8vIERyYXdpbmcgYXQgMTAgZnBzXG4gICAqICAgICAgICB9XG4gICAqICAgICAgfTtcbiAgICogICAgICBsb29wKCk7XG4gICAqICAgIH0pO1xuICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAqXG4gICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAqICAgICAgbXlIdG1sVGFyZ2V0LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICogICAgICAgIHZpZGVvU291cmNlOiBncmF5VmlkZW9UcmFja1xuICAgKiAgICAgIH0pO1xuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpXG4gICAgICAgIC50aGVuKGNvbnN0cmFpbnRzID0+IHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gIC8qKlxuICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgKi9cbiAgZW5hYmxlUHJvZE1vZGUoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2cgPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS5kZWJ1ZyA9ICgpID0+IHsgfTtcbiAgICBjb25zb2xlLmluZm8gPSAoKSA9PiB7IH07XG4gICAgY29uc29sZS53YXJuID0gKCkgPT4geyB9O1xuICB9XG4gIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuXG4gIC8qKlxuICAgKiBTZXQgT3BlblZpZHUgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb25zLiBDdXJyZW50bHkgYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXSBmb3IgbW9yZSBkZXRhaWxzKTpcbiAgICogLSBgaWNlU2VydmVyc2A6IHNldCBjdXN0b20gU1RVTi9UVVJOIHNlcnZlcnMgdG8gYmUgdXNlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAqIC0gYHNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uYDogdXJsIHRvIGEgY3VzdG9tIHNjcmVlbiBzaGFyZSBleHRlbnNpb24gZm9yIENocm9tZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLCBiYXNlZCBvbiBvdXJzIFtodHRwczovL2dpdGh1Yi5jb20vT3BlblZpZHUvb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbl0oaHR0cHM6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24pXG4gICAqIC0gYHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uc2A6IGN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZVxuICAgKi9cbiAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICB9XG5cblxuICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBnZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMocHVibGlzaGVyUHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW1Db25zdHJhaW50cz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgYXVkaW8sIHZpZGVvO1xuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICBhdWRpbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXVkaW8gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXVkaW8gPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICB2aWRlbyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlkZW8gPSB7XG4gICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVkaWFDb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW8sXG4gICAgICAgIHZpZGVvXG4gICAgICB9O1xuXG4gICAgICBpZiAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPSB7IGRldmljZUlkOiB7IGV4YWN0OiBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhQ29uc3RyYWludHMudmlkZW8pIHtcblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICBjb25zdCB3aWR0aEFuZEhlaWdodCA9IHB1Ymxpc2hlclByb3BlcnRpZXMucmVzb2x1dGlvbi50b0xvd2VyQ2FzZSgpLnNwbGl0KCd4Jyk7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMF0pO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFsxXSk7XG4gICAgICAgICAgKG1lZGlhQ29uc3RyYWludHMudmlkZW8gYXMgYW55KS53aWR0aC5pZGVhbCA9IHdpZHRoO1xuICAgICAgICAgIChtZWRpYUNvbnN0cmFpbnRzLnZpZGVvIGFzIGFueSkuaGVpZ2h0LmlkZWFsID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAobWVkaWFDb25zdHJhaW50cy52aWRlbyBhcyBhbnkpLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICYmIHR5cGVvZiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgaWYgKHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSAmJiBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnd2luZG93JykgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nICYmIHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKSkge1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCkpIHtcblxuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQsICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICsgcGxhdGZvcm0ubmFtZSk7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBcInNjcmVlbjpcIjtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICg8YW55Pm1lZGlhQ29uc3RyYWludHNbJ3ZpZGVvJ10pID0ge1xuICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG5cbiAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uICYmICEocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkgJiYgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0U2NyZWVuQ29uc3RyYWludHMoKGVycm9yLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvciB8fCAhIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uSWQgPSB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKS5wb3AoKSEhLnRyaW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVELCAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgKDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0IChDaHJvbWUgPj0gNzIsIEZpcmVmb3ggPj0gNTIpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobWVkaWFDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9IHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmdBdXRvLmdldFNjcmVlbklkKGZpcmVmb3hTdHJpbmcsIChlcnJvciwgc291cmNlSWQsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvblVybCA9ICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL29wZW52aWR1LXNjcmVlbnNoYXJpbmcvbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVELCAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG1lZGlhQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9ICdzY3JlZW4nO1xuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXG4gICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydkZXZpY2VJZCddID0geyBleGFjdDogcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSB9O1xuICAgICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtZWRpYUNvbnN0cmFpbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBzdGFydFdzKG9uQ29ubmVjdFN1Y2NlczogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgIHNlbmRDbG9zZU1lc3NhZ2U6IGZhbHNlLFxuICAgICAgd3M6IHtcbiAgICAgICAgdXJpOiB0aGlzLndzVXJpLFxuICAgICAgICB1c2VTb2NrSlM6IGZhbHNlLFxuICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0aW5nOiB0aGlzLnJlY29ubmVjdGluZ0NhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgICAgcnBjOiB7XG4gICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgcGFydGljaXBhbnRKb2luZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHBhcnRpY2lwYW50TGVmdDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0LmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgcmVjb3JkaW5nU3RvcHBlZDogdGhpcy5zZXNzaW9uLm9uUmVjb3JkaW5nU3RvcHBlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBmaWx0ZXJFdmVudERpc3BhdGNoZWQ6IHRoaXMuc2Vzc2lvbi5vbkZpbHRlckV2ZW50RGlzcGF0Y2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKVxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5qc29uUnBjQ2xpZW50ID0gbmV3IFJwY0J1aWxkZXIuY2xpZW50cy5Kc29uUnBjQ2xpZW50KGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgY2xvc2VXcygpOiB2b2lkIHtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMiwgXCJDb25uZWN0aW9uIGNsb3NlZCBieSBjbGllbnRcIik7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgc2VuZFJlcXVlc3QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogYW55LCBjYWxsYmFjaz8pOiB2b2lkIHtcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgIHBhcmFtcyA9IHt9O1xuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMud3NVcmk7XG4gIH1cblxuICAvKipcbiAgICogQGhpZGRlblxuICAgKi9cbiAgZ2V0U2VjcmV0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIGdldFJlY29yZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlY29yZGVyO1xuICB9XG5cblxuICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QnKTtcbiAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ2Nvbm5lY3QnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihcIm5ldHdvcmtEaXNjb25uZWN0XCIpO1xuICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAxLCBcIlJlY29ubmVjdGlvbiBmYXVsdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQucmVzZXRQaW5nKCk7XG4gICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZXNzaW9uIGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybignU2Vzc2lvbiBpbnN0YW5jZSBub3QgZm91bmQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBQdWJsaXNoZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9QdWJsaXNoZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuXG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIFBhY2tzIGxvY2FsIG1lZGlhIHN0cmVhbXMuIFBhcnRpY2lwYW50cyBjYW4gcHVibGlzaCBpdCB0byBhIHNlc3Npb24uIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQgW1tQdWJsaXNoZXIuc3Vic2NyaWJlVG9SZW1vdGVdXSB3aXRoIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgICgqZmFsc2UqIGJ5IGRlZmF1bHQpXG4gICAgICovXG4gICAgaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSB0byB3aGljaCB0aGUgUHVibGlzaGVyIGJlbG9uZ3NcbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvLyBJbml0aWFsaXplZCBieSBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKVxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NEZW5pZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgSUVBZGFwdGVyOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKG5ldyBTdHJlYW0oKCEhb3BlbnZpZHUuc2Vzc2lvbikgPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7IHB1Ymxpc2hlclByb3BlcnRpZXM6IHByb3BlcnRpZXMsIG1lZGlhQ29uc3RyYWludHM6IHt9IH0pLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ2F1ZGlvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoQXVkaW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaEF1ZGlvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIG9yIHVucHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIHZhbHVlLCAhdmFsdWUsICdwdWJsaXNoVmlkZW8nKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCB2YWx1ZSwgIXZhbHVlLCAncHVibGlzaFZpZGVvJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKHZhbHVlID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZWRUb1JlbW90ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgc3VwZXIub24odHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncmVtb3RlVmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3JlbW90ZVZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IFB1Ymxpc2hlciB7XG4gICAgICAgIHN1cGVyLm9uY2UodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZW1vdGVWaWRlb1BsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkgJiYgdGhpcy52aWRlb3NbMF0gJiYgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAxMjUwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyBhbmQgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoISFtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gbnVsbCkgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA6ICEhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gbWVkaWFTdHJlYW07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddIHx8IHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaU9TIElvbmljIG9yIFNhZmFyaS4gTGltaXRhdGlvbjogY2Fubm90IHNldCB2aWRlb0RpbWVuc2lvbnMgZGlyZWN0bHksIGFzIHRoZSB2aWRlb1JlZmVyZW5jZSBpcyBub3QgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm90IGFkZGVkIHRvIERPTS4gTXVzdCBhZGQgaXQgdG8gRE9NIGFuZCB3YWl0IGZvciB2aWRlb1dpZHRoIGFuZCB2aWRlb0hlaWdodCBwcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlkZW9EaW1lbnNpb25zU2V0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb1dpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnNTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggbm8gc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gY2FuIGJlIHNldCBkaXJlY3RseSBmcm9tIE1lZGlhU3RyZWFtIChnZXRTZXR0aW5ncylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmllbnRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZm9yIG1vYmlsZSBkZXZpY2VzICh3aWR0aCBhbmQgaGVpZ2h0IGFyZSByZXZlcnNlZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdpT1MnIHx8IHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnQW5kcm9pZCcpICYmICh3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9iaWxlIHBvcnRyYWl0IG1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3aWR0aCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGggc2NyZWVuIHNoYXJlLCB2aWRlbyBkaW1lbnNpb24gbXVzdCBiZSBnb3QgZnJvbSBhIHZpZGVvIGVsZW1lbnQgKG9ubG9hZGVkbWV0YWRhdGEgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcmVmb3hTZXR0aW5ncyA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAocGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJykgPyB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGggOiBmaXJlZm94U2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IChwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnT3BlcmEnKSA/IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQgOiBmaXJlZm94U2V0dGluZ3MuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ld1dpZHRoICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMud2lkdGggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgd2lkdGg6IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCwgaGVpZ2h0OiB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkodGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAnc2NyZWVuUmVzaXplZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICd2aWRlb0RpbWVuc2lvbnMnLCB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMsIG9sZFZhbHVlLCAnc2NyZWVuUmVzaXplZCcpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvRGltZW5zaW9ucycsIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucywgb2xkVmFsdWUsICdzY3JlZW5SZXNpemVkJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGF1ZGlvT25seVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUNDRVNTX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgKyAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMudmlkZW8pLmRldmljZUlkISEpLmV4YWN0ICsgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhRXJyb3IgPSBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiQXVkaW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIlZpZGVvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgKyBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IFwiVmlkZW8gaW5wdXQgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgdmFsdWUgcGFzc2VkIGZvciBjb25zdHJhaW50ICdcIiArIGVycm9yLmNvbnN0cmFpbnQgKyBcIidcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWJvcnRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdHJlYWRhYmxlZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5ldyBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC4gTm8gY29uc3RyYWludHMgbmVlZGVkIGlmXG4gICAgICAgICAgICAvLyAtIHZpZGVvIHRyYWNrIGlzIGdpdmVuIGFuZCBubyBhdWRpb1xuICAgICAgICAgICAgLy8gLSBhdWRpbyB0cmFjayBpcyBnaXZlbiBhbmQgbm8gdmlkZW9cbiAgICAgICAgICAgIC8vIC0gYm90aCB2aWRlbyBhbmQgYXVkaW8gdHJhY2tzIGFyZSBnaXZlblxuICAgICAgICAgICAgaWYgKCh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiAhdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlKVxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjayAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKCg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMuYXVkaW9Tb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW1UcmFja3MgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrIC0ganVzdCBjYWxsIGNhbGxiYWNrIHdpdGggbmV3IE1lZGlhU3RyZWFtKCkgYW5kIGxldCBpdCBoYW5kbGUgdGhlIHNvdXJjZXNcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBhcyB3ZSBkbyBub3QgbmVlZCB0byBwcm9jZXNzIGZ1cnRoZXJcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAudGhlbihteUNvbnN0cmFpbnRzID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSB8fCB0aGlzLnN0cmVhbS5pc1NlbmRBdWRpbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gKChjb25zdHJhaW50cy5hdWRpbyA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpID8gZmFsc2UgOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBlcm1pc3Npb25EaWFsb2dUaW1lcih0aW1lRm9yRGlhbG9nRXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgcGxhdGZvcm0ubmFtZSAhPT0gJ0VsZWN0cm9uJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lIHdoZW4gY2FsbGluZyAnT3BlblZpZHUuaW5pdFB1Ymxpc2hlcidcIikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmICgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgPiB3YWl0VGltZSkge1xuICAgICAgICAgICAgLy8gUGVybWlzc2lvbiBkaWFsb2cgd2FzIHNob3duIGFuZCBub3cgaXMgY2xvc2VkXG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nQ2xvc2VkJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuL1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9DYXBhYmlsaXRpZXMnO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU2lnbmFsT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU2lnbmFsT3B0aW9ucyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Db25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBPYmpNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PYmpNYXAnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudCc7XG5pbXBvcnQgeyBSZWNvcmRpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudCc7XG5pbXBvcnQgeyBTaWduYWxFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIG9iamVjdCBpcyBkZWZpbmVkIG9ubHkgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQsIGFuZCBjYW4gYmUgcmV0cmlldmVkIHN1YnNjcmliaW5nIHRvIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIFNlc3Npb25cbiAgICAgKi9cbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbGxlY3Rpb24gb2YgYWxsIFN0cmVhbU1hbmFnZXJzIG9mIHRoaXMgU2Vzc2lvbiAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcnM6IFN0cmVhbU1hbmFnZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGRlZmluaW5nIHRoZSBtZXRob2RzIHRoYXQgdGhlIGNsaWVudCBpcyBhYmxlIHRvIGNhbGwuIFRoZXNlIGFyZSBkZWZpbmVkIGJ5IHRoZSByb2xlIG9mIHRoZSB0b2tlbiB1c2VkIHRvIGNvbm5lY3QgdG8gdGhlIFNlc3Npb24uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBPYmpNYXA8Ym9vbGVhbj4gPSB7fTtcblxuICAgIC8qKlx0XG4gICAgICogQGhpZGRlblx0XG4gICAgICovXG4gICAgaXNGaXJzdElvbmljSW9zU3Vic2NyaWJlciA9IHRydWU7XG4gICAgLyoqXHRcbiAgICAgKiBAaGlkZGVuXHRcbiAgICAgKi9cbiAgICBjb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE9iak1hcDxDb25uZWN0aW9uPiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIG9iamVjdCB3aWxsIGJlIGF2YWlsYWJsZSBhbmQgcHJvcGVybHkgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZmlyc3QgZGlzcGF0Y2ggb25lIG9yIG1vcmUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kOlxuICAgICAqIC0gRmlyc3Qgb25lIGZvciB5b3VyIG93biBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCwgc28geW91IGNhbiByZXRyaWV2ZSBbW1Nlc3Npb24uY29ubmVjdGlvbl1dIHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IGZvciBlYWNoIHJlbW90ZSBhY3RpdmUgW1tQdWJsaXNoZXJdXSB0aGF0IHdhcyBhbHJlYWR5IHN0cmVhbWluZ1xuICAgICAqIHdoZW4gY29ubmVjdGluZywganVzdCBhZnRlciBkaXNwYXRjaGluZyBhbGwgcmVtb3RlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgdG8gd2hpY2ggeW91IG11c3Qgc3Vic2NyaWJlIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELCAnQnJvd3NlciAnICsgcGxhdGZvcm0ubmFtZSArICcgKHZlcnNpb24gJyArIHBsYXRmb3JtLnZlcnNpb24gKyAnKSBmb3IgJyArIHBsYXRmb3JtLm9zISEuZmFtaWx5ICsgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBwdWJsaXNoaW5nIHRvIHRoZSBzZXNzaW9uLlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzLCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCk6IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRvIGEgYHN0cmVhbWAsIGFkZGluZyBhIG5ldyBIVE1MIHZpZGVvIGVsZW1lbnQgdG8gRE9NIHdpdGggYHN1YnNjcmliZXJQcm9wZXJ0aWVzYCBzZXR0aW5ncy4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgaW4gdGhlIGNhbGxiYWNrIG9mIGBzdHJlYW1DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZG9jcy9ob3ctZG8taS9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcywgcGFyYW00PzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiAodHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJykgPyAoKHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZycpID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXSA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZSkgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86ICh0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnKSA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiAodHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJykgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgKHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICovXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50KTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPjtcblxuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllcz86IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxTdWJzY3JpYmVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTdWJzY3JpYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3Vic2NyaWJlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAgICpcbiAgICAgKiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBzbyB0aGV5IGNhbiBzdWJzY3JpYmUgdG8gaXQuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgV2ViUlRDUGVlciBjb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJywgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBub3QgeW91ciBsb2NhbCBDb25uZWN0aW9uLicgK1xuICAgICAgICAgICAgICAgIFwiT25seSBtb2RlcmF0b3JzIGNhbiBmb3JjZSB1bnB1Ymxpc2ggb24gcmVtb3RlIFN0cmVhbXMgdmlhICdmb3JjZVVucHVibGlzaCcgbWV0aG9kXCIsIHN0cmVhbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgcHVibGlzaGVyLCAnc3RyZWFtRGVzdHJveWVkJywgcHVibGlzaGVyLnN0cmVhbSwgJ3VucHVibGlzaCcpO1xuICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgeyBjb25uZWN0aW9uSWQ6IGNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2ZvcmNlVW5wdWJsaXNoJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZm9yY2luZyB1bnB1Ymxpc2ggZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGZvcmNlIGFuIHVucHVibGlzaGluZ1wiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZvcmNpbmcgdW5wdWJsaXNoIGNvcnJlY3RseSBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBvbmUgc2lnbmFsLiBgc2lnbmFsYCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiBgYGBqc29uXG4gICAgICoge2RhdGE6c3RyaW5nLCB0bzpDb25uZWN0aW9uW10sIHR5cGU6c3RyaW5nfVxuICAgICAqIGBgYFxuICAgICAqIEFsbCB1c2VycyBzdWJzY3JpYmVkIHRvIHRoYXQgc2lnbmFsIChgc2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCAuLi4pYCBvciBgc2Vzc2lvbi5vbignc2lnbmFsJywgLi4uKWAgZm9yIGFsbCBzaWduYWxzKSBhbmQgd2hvc2UgQ29ubmVjdGlvbiBvYmplY3RzIGFyZSBpbiBgdG9gIGFycmF5IHdpbGwgcmVjZWl2ZSBpdC4gVGhlaXIgbG9jYWxcbiAgICAgKiBTZXNzaW9uIG9iamVjdHMgd2lsbCBkaXNwYXRjaCBhIGBzaWduYWxgIG9yIGBzaWduYWw6dHlwZWAgZXZlbnQuIFNlZSBbW1NpZ25hbEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdzZW5kTWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1zdHJpbmctbGl0ZXJhbCAqL1xuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcblxuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIHx8IHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLnNwZWFraW5nRXZlbnRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMsIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0ciAmJiBzdHIuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyLmVuYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHwgU2lnbmFsRXZlbnQgfCBTdHJlYW1FdmVudCB8IENvbm5lY3Rpb25FdmVudCB8IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfCBSZWNvcmRpbmdFdmVudCkgPT4gdm9pZCk6IFNlc3Npb24ge1xuXG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBlbmFibGUgaGFyayBpbiBhbGwgb2YgdGhlbVxuICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uSWQgaW4gdGhpcy5yZW1vdGVDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ciA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW07XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyICYmIHN0ci5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZW5hYmxlT25jZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmYodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfCBTaWduYWxFdmVudCB8IFN0cmVhbUV2ZW50IHwgQ29ubmVjdGlvbkV2ZW50IHwgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB8IFJlY29yZGluZ0V2ZW50KSA9PiB2b2lkKTogU2Vzc2lvbiB7XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJyB8fCB0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgdGhpcy5zcGVha2luZ0V2ZW50c0VuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zLCBkaXNhYmxlIGhhcmsgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbklkIGluIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cikge1xuICAgICAgICAgICAgICAgICAgICBzdHIuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKHJlc3BvbnNlOiBDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24ocmVzcG9uc2UuaWQsICcnKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Nvbm5lY3Rpb24gJyArIHJlc3BvbnNlLmlkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tyZXNwb25zZS5pZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsICdSZW1vdGUgY29ubmVjdGlvbiAnICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiIHVua25vd24gd2hlbiAnb25QYXJ0aWNpcGFudExlZnQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbc3RyZWFtLnN0cmVhbUlkXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQocmVzcG9uc2U6IENvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWRbY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWRdKSB7XG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiBzdHJlYW0uc3Vic2NyaWJlKCkgaW4gXCJvblBhcnRpY2lwYW50UHVibGlzaGVkXCIgYW5kIGluIFwiam9pblJvb21cIiBycGMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvbmRpdGlvbiBpcyBmYWxzZSBpZiBvcGVudmlkdS1zZXJ2ZXIgc2VuZHMgXCJwYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGV2ZW50IHRvIGEgc3Vic2NyaWJlciBwYXJ0aWNpcGFudCB0aGF0IGhhc1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc3Vic2NyaWJlZCB0byBjZXJ0YWluIHN0cmVhbSBpbiB0aGUgY2FsbGJhY2sgb2YgXCJqb2luUm9vbVwiIG1ldGhvZFxuXG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldCB0aGUgZXhpc3RpbmcgQ29ubmVjdGlvbiBjcmVhdGVkIG9uICdvblBhcnRpY2lwYW50Sm9pbmVkJyBmb3JcbiAgICAgICAgLy8gZXhpc3RpbmcgcGFydGljaXBhbnRzIG9yIGNyZWF0ZSBhIG5ldyBvbmUgZm9yIG5ldyBwYXJ0aWNpcGFudHNcbiAgICAgICAgbGV0IGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihyZXNwb25zZS5pZCwgXCJSZW1vdGUgY29ubmVjdGlvbiAnXCIgKyByZXNwb25zZS5pZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnLiBcIiArXG4gICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAudGhlbihjb24gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ub3B0aW9ucyA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMocmVzcG9uc2Uuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKG1zZyk6IHZvaWQge1xuICAgICAgICBpZiAobXNnLmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKG1zZy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKG1zZy5jb25uZWN0aW9uSWQsIFwiUmVtb3RlIGNvbm5lY3Rpb24gJ1wiICsgbXNnLmNvbm5lY3Rpb25JZCArIFwiJyB1bmtub3duIHdoZW4gJ29uUGFydGljaXBhbnRVbnB1Ymxpc2hlZCcuIFwiICtcbiAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICsgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXModGhpcy5yZW1vdGVDb25uZWN0aW9ucykpKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtLCBtc2cucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtzdHJlYW1JZF07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY291bnREb3duRm9ySW9uaWNJb3NTdWJzY3JpYmVyc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGlmIChtc2cuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgbXNnLnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihtc2cuZnJvbSwgXCJDb25uZWN0aW9uICdcIiArIG1zZy5mcm9tICsgXCInIHVua25vdyB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiXG4gICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHRoaXMucmVtb3RlQ29ubmVjdGlvbnMpKSArICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKVxuXG4gICAgICAgICAgICAudGhlbihjb25uZWN0aW9uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZy50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChtc2cudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBtc2cudHlwZSwgbXNnLmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChvcGVuVmlkdUVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKG1zZyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBtc2cuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcbiAgICAgICAgICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChtc2cucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBtc2cubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5hdWRpb0FjdGl2ZSA9IG1zZy5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5uZXdWYWx1ZSA9IG1zZy5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvQWN0aXZlID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UobXNnLm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gbXNnLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSAoT2JqZWN0LmtleXMobXNnLm5ld1ZhbHVlKS5sZW5ndGggPiAwKSA/IG1zZy5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc2cubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKG1zZy5uZXdWYWx1ZS50eXBlLCBtc2cubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gbXNnLm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgbXNnLnByb3BlcnR5LCBtc2cubmV3VmFsdWUsIG9sZFZhbHVlLCBtc2cucmVhc29uKV0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBtc2cucHJvcGVydHksIG1zZy5uZXdWYWx1ZSwgb2xkVmFsdWUsIG1zZy5yZWFzb24pXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICsgbXNnLnN0cmVhbUlkICsgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArIG1zZy5jb25uZWN0aW9uSWQgKyBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1zZy5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdXIgc3RyZWFtIGhhcyBiZWVuIGZvcmNlZGx5IGNoYW5nZWQgKGZpbHRlciBmZWF0dXJlKVxuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihtc2cuY29ubmVjdGlvbklkLCAnUmVtb3RlIGNvbm5lY3Rpb24gJyArIG1zZy5jb25uZWN0aW9uSWQgKyBcIiB1bmtub3duIHdoZW4gJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJy4gXCIgK1xuICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zKSkpXG4gICAgICAgICAgICAgICAgLnRoZW4oY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9wZW5WaWR1RXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgY29tcG9uZW50OiBtc2cuY29tcG9uZW50LFxuICAgICAgICAgICAgZm91bmRhdGlvbjogbXNnLmZvdW5kYXRpb24sXG4gICAgICAgICAgICBpcDogbXNnLmlwLFxuICAgICAgICAgICAgcG9ydDogbXNnLnBvcnQsXG4gICAgICAgICAgICBwcmlvcml0eTogbXNnLnByaW9yaXR5LFxuICAgICAgICAgICAgcHJvdG9jb2w6IG1zZy5wcm90b2NvbCxcbiAgICAgICAgICAgIHJlbGF0ZWRBZGRyZXNzOiBtc2cucmVsYXRlZEFkZHJlc3MsXG4gICAgICAgICAgICByZWxhdGVkUG9ydDogbXNnLnJlbGF0ZWRQb3J0LFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICB0Y3BUeXBlOiBtc2cudGNwVHlwZSxcbiAgICAgICAgICAgIHVzZXJuYW1lRnJhZ21lbnQ6IG1zZy51c2VybmFtZUZyYWdtZW50LFxuICAgICAgICAgICAgdHlwZTogbXNnLnR5cGUsXG4gICAgICAgICAgICB0b0pTT046ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBjYW5kaWRhdGU6IG1zZy5jYW5kaWRhdGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKG1zZy5zZW5kZXJDb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBtc2cuc2VuZGVyQ29ubmVjdGlvbklkICsgJyBvd25pbmcgZW5kcG9pbnQgJyArIG1zZy5lbmRwb2ludE5hbWUgKyAnLiBJY2UgY2FuZGlkYXRlIHdpbGwgYmUgaWdub3JlZDogJyArIGNhbmRpZGF0ZSlcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5nZXRXZWJSdGNQZWVyKCkuYWRkSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBtc2cuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2gob3BlblZpZHVFcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFt7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBzZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCArICcgd2FpdGluZyBmb3IgcmVjb25uZWN0Jyk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUud2FybignUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICAvLyB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblJlY292ZXJlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcyk6IHZvaWQge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSk7XG4gICAgICAgIGNvbnN0IGVyciA9IHBhcmFtcy5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW3tcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvci4gUGFyYW1zOicsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLmlkLCByZXNwb25zZS5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQocmVzcG9uc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0b3BwZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdG9wcGVkJywgcmVzcG9uc2UuaWQsIHJlc3BvbnNlLm5hbWUsIHJlc3BvbnNlLnJlYXNvbildKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogcmVzcG9uc2UgPSB7Y29ubmVjdGlvbklkOiBzdHJpbmcsIHN0cmVhbUlkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0fVxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZDogc3RyaW5nID0gcmVzcG9uc2UuY29ubmVjdGlvbklkO1xuICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gcmVzcG9uc2Uuc3RyZWFtSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZClcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbygnRmlsdGVyIGV2ZW50IGRpc3BhdGNoZWQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuaGFuZGxlcnNbcmVzcG9uc2UuZXZlbnRUeXBlXShuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgcmVzcG9uc2UuZXZlbnRUeXBlLCByZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW1pdEV2ZW50KHR5cGU6IHN0cmluZywgZXZlbnRBcnJheTogYW55W10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQodHlwZSwgZXZlbnRBcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxlYXZlKGZvcmNlZDogYm9vbGVhbiwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgY29uc29sZS5pbmZvKCdMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD0nICsgZm9yY2VkICsgJyknKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0YXJ0V3MoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogKCEhdG9rZW4pID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZGVzY3JpcHRpb24gPyBwbGF0Zm9ybS5kZXNjcmlwdGlvbiA6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgY2FwYWJpbGl0aWVzIG9iamVjdCB3aXRoIHRoZSByb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQgPSByZXNwb25zZS5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2gocGFydGljaXBhbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcGFydGljaXBhbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uY29ubmVjdGlvbklkXSA9IGNvbm5lY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZFtjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goY29ubmVjdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCBjb25uZWN0aW9uLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goc3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzP1xcOilcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS5zcGxpdCgnPScpKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHZhbHVlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSA8c3RyaW5nPnF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXTtcbiAgICAgICAgICAgIGNvbnN0IHJlY29yZGVyID0gcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuVXNlcm5hbWUgPSBxdWVyeVBhcmFtc1sndHVyblVzZXJuYW1lJ107XG4gICAgICAgICAgICBjb25zdCB0dXJuQ3JlZGVudGlhbCA9IHF1ZXJ5UGFyYW1zWyd0dXJuQ3JlZGVudGlhbCddO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IHF1ZXJ5UGFyYW1zWydyb2xlJ107XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0ludGVydmFsID0gcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1U2VydmVyVmVyc2lvbiA9IHF1ZXJ5UGFyYW1zWyd2ZXJzaW9uJ107XG5cbiAgICAgICAgICAgIGlmICghIXNlY3JldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcmVjb3JkZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXR1cm5Vc2VybmFtZSAmJiAhIXR1cm5DcmVkZW50aWFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R1blVybCA9ICdzdHVuOicgKyB1cmwuaG9zdG5hbWUgKyAnOjM0NzgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR1cm5VcmwxID0gJ3R1cm46JyArIHVybC5ob3N0bmFtZSArICc6MzQ3OCc7XG4gICAgICAgICAgICAgICAgY29uc3QgdHVyblVybDIgPSB0dXJuVXJsMSArICc/dHJhbnNwb3J0PXRjcCc7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW1xuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFtzdHVuVXJsXSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHVybHM6IFt0dXJuVXJsMSwgdHVyblVybDJdLCB1c2VybmFtZTogdHVyblVzZXJuYW1lLCBjcmVkZW50aWFsOiB0dXJuQ3JlZGVudGlhbCB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVFVSTiB0ZW1wIGNyZWRlbnRpYWxzIFsnICsgdHVyblVzZXJuYW1lICsgJzonICsgdHVybkNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhcm9sZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IHJvbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF3ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gK3dlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISFvcGVudmlkdVNlcnZlclZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogXCIgKyBvcGVudmlkdVNlcnZlclZlcnNpb24pO1xuICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVNlcnZlclZlcnNpb24gIT09IHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignT3BlblZpZHUgU2VydmVyICgnICsgb3BlbnZpZHVTZXJ2ZXJWZXJzaW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpIGFuZCBPcGVuVmlkdSBCcm93c2VyICgnICsgdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSB2ZXJzaW9ucyBkbyBOT1QgbWF0Y2guIFRoZXJlIG1heSBiZSBpbmNvbXBhdGliaWxpdGllcycpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gJ3dzczovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gJ2h0dHBzOi8vJyArIHVybC5ob3N0O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUb2tlbiBcIicgKyB0b2tlbiArICdcIiBpcyBub3QgdmFsaWQnKVxuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBJbmJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0luYm91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL091dGJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBXZWJSdGNQZWVyLCBXZWJSdGNQZWVyU2VuZG9ubHksIFdlYlJ0Y1BlZXJSZWN2b25seSwgV2ViUnRjUGVlclNlbmRyZWN2IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNQZWVyL1dlYlJ0Y1BlZXInO1xuaW1wb3J0IHsgV2ViUnRjU3RhdHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1N0YXRzL1dlYlJ0Y1N0YXRzJztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIGltcGxlbWVudHMgRXZlbnREaXNwYXRjaGVyIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIG9iamVjdCB0aGF0IGlzIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZSByYXRlIG9mIHRoZSB2aWRlbyBpbiBmcmFtZXMgcGVyIHNlY29uZC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWYgdGhlIFtbUHVibGlzaGVyXV0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24gW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gbWV0aG9kXG4gICAgICovXG4gICAgZnJhbWVSYXRlPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhIHZpZGVvIHRyYWNrIG9yIG5vdFxuICAgICAqL1xuICAgIGhhc1ZpZGVvOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyBhbiBhdWRpbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNBdWRpbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgdGhlIHZpZGVvIHRyYWNrIG11dGVkIG9yIHVubXV0ZWQuIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaFZpZGVvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgdmlkZW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSBhdWRpbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc0F1ZGlvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciBwdWJsaXNoaW5nIHRoZSBzdHJlYW0gY2FsbHMgW1tQdWJsaXNoZXIucHVibGlzaEF1ZGlvXV0uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICAgKiBieSB0aGUgU2Vzc2lvbiBvYmplY3QgYXMgd2VsbCBhcyBieSB0aGUgYWZmZWN0ZWQgU3Vic2NyaWJlci9QdWJsaXNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYXVkaW9BY3RpdmU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGJlbG9uZ3MgdG8gYS4uLlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBzdHJlYW1JZGAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIFtbU2Vzc2lvbi5wdWJsaXNoXV1cbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgc3RyZWFtIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcykuIERlcGVuZGluZyBvbiB0aGUgb3duZXIgb2YgdGhpcyBzdHJlYW06XG4gICAgICogLSBTdWJzY3JpYmVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgYWx3YXlzIGRlZmluZWRcbiAgICAgKiAtIFB1Ymxpc2hlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBgXCJDQU1FUkFcImAsIGBcIlNDUkVFTlwiYCBvciBgXCJDVVNUT01cImAgKHRoZSBsYXR0ZXIgd2hlbiBbW1B1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VdXSBpcyBhIE1lZGlhU3RyZWFtVHJhY2sgd2hlbiBjYWxsaW5nIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dKS5cbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoW1tQdWJsaXNoZXJdXSBvciBbW1N1YnNjcmliZXJdXSkgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhpcyBzdHJlYW0gaW4gdGhlIERPTVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaWR0aCBhbmQgaGVpZ2h0IGluIHBpeGVscyBvZiB0aGUgZW5jb2RlZCB2aWRlbyBzdHJlYW0uIElmIFtbaGFzVmlkZW9dXSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvRGltZW5zaW9uczogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gICAgICpcbiAgICAgKiBGaWx0ZXIgYXBwbGllZCB0byB0aGUgU3RyZWFtLiBZb3UgY2FuIGFwcGx5IGZpbHRlcnMgYnkgY2FsbGluZyBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBleGVjdXRlIG1ldGhvZHMgb2YgdGhlIGFwcGxpZWQgZmlsdGVyIHdpdGhcbiAgICAgKiBbW0ZpbHRlci5leGVjTWV0aG9kXV0gYW5kIHJlbW92ZSBpdCB3aXRoIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dLiBCZSBhd2FyZSB0aGF0IHRoZSBjbGllbnQgY2FsbGluZyB0aGlzIG1ldGhvZHMgbXVzdCBoYXZlIHRoZVxuICAgICAqIG5lY2Vzc2FyeSBwZXJtaXNzaW9uczogdGhlIHRva2VuIG93bmVkIGJ5IHRoZSBjbGllbnQgbXVzdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGVkIGBhbGxvd2VkRmlsdGVyc2AgYXJyYXkuXG4gICAgICovXG4gICAgZmlsdGVyOiBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1BlZXI6IFdlYlJ0Y1BlZXI7XG4gICAgcHJpdmF0ZSBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW07XG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0czogV2ViUnRjU3RhdHM7XG5cbiAgICBwcml2YXRlIGlzU3Vic2NyaWJlVG9SZW1vdGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluYm91bmRTdHJlYW1PcHRzOiBJbmJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCA9IGZhbHNlO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgb3B0aW9uczogSW5ib3VuZFN0cmVhbU9wdGlvbnMgfCBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfCB7fSkge1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2lkJykpIHtcbiAgICAgICAgICAgIC8vIEluYm91bmRTdHJlYW1PcHRpb25zOiBzdHJlYW0gYmVsb25ncyB0byBhIFN1YnNjcmliZXJcbiAgICAgICAgICAgIHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgPSA8SW5ib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIHRoaXMuaGFzQXVkaW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuaGFzVmlkZW87XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9BY3RpdmUgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSAodGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5mcmFtZVJhdGUgPT09IC0xKSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiAoT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIpLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QgJiYgT2JqZWN0LmtleXModGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXIubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5maWx0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdXRib3VuZFN0cmVhbU9wdGlvbnM6IHN0cmVhbSBiZWxvbmdzIHRvIGEgUHVibGlzaGVyXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IDxPdXRib3VuZFN0cmVhbU9wdGlvbnM+b3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5oYXNBdWRpbyA9IHRoaXMuaXNTZW5kQXVkaW8oKTtcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmlzU2VuZFZpZGVvKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9BY3RpdmUgPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSYXRlID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gJ0NVU1RPTSc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9IHRoaXMuaXNTZW5kU2NyZWVuKCkgPyAnU0NSRUVOJyA6ICdDQU1FUkEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtICsgJ10gdXBkYXRlZCBpbiBzdHJlYW0gWycgKyB0aGlzLnN0cmVhbUlkICsgJ10nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uKHR5cGU6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZSh0eXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW1JZCArIFwiJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtSWQgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUucmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vZmYodHlwZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciB0byB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gU2VlIFtbRmlsdGVyLnR5cGVdXVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSBbW0ZpbHRlci5vcHRpb25zXV1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB0byB0aGUgYXBwbGllZCBmaWx0ZXIgaWYgc3VjY2VzcyBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgYXBwbHlGaWx0ZXIodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpOiBQcm9taXNlPEZpbHRlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdBcHBseWluZyBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSAhIW9wdGlvbnMgPyBvcHRpb25zIDoge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdhcHBseUZpbHRlcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9ucyB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWU6IEZpbHRlciA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHByZXZpb3VzbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcHJldmlvdXNseSBhcHBsaWVkIGZpbHRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIHJlbW92ZUZpbHRlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyJyxcbiAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlbW92ZSBhIGZpbHRlclwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW25ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0czogT3V0Ym91bmRTdHJlYW1PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gb3V0Ym91bmRTdHJlYW1PcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VXZWJSdGNQZWVyKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VuZGVyQW5kQ3VzdG9tVHJhY2s6IGJvb2xlYW4gPSAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmRpc3Bvc2UoaXNTZW5kZXJBbmRDdXN0b21UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArIFwiV2ViUlRDUGVlciBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBjbG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbygoISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCAnIDogJ1JlbW90ZSAnKSArIFwiTWVkaWFTdHJlYW0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtSWQgKyAnXSBpcyBub3cgZGlzcG9zZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlICE9PSBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nKSB7XG4gICAgICAgICAgICBzY3JlZW4gPSB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldFNwZWVjaEV2ZW50SWZOb3RFeGlzdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaGFya09wdGlvbnMgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gKHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicpID8gaGFya09wdGlvbnMuaW50ZXJ2YWwgOiA1MDtcbiAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9ICh0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJykgPyBoYXJrT3B0aW9ucy50aHJlc2hvbGQgOiAtNTA7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0U3BlZWNoRXZlbnRJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZCldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VTcGVha2luZ0V2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdGFydFNwZWFraW5nRXZlbnRFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdFdmVudEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW25ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wdWJsaXNoZXJTdG9wU3BlYWtpbmdFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaGVyU3RvcFNwZWFraW5nRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVNwZWFraW5nRXZlbnRzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlU3BlYWtpbmdFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZvbHVtZUNoYW5nZUV2ZW50RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIC8vICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHVibGlzaGVyU3RhcnRTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnB1Ymxpc2hlclN0b3BTcGVha2luZ0V2ZW50RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCBoYXJrRXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VWb2x1bWVDaGFuZ2VFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTcGVlY2hFdmVudElmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy52b2x1bWVDaGFuZ2VFdmVudEVuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIGhhcmtFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgdmFsdWUpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlVm9sdW1lQ2hhbmdlRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uc3BlYWtpbmdFdmVudHNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnIGFuZC9vciBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIGV2ZW50cyBhcmUgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2Vzc1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudm9sdW1lQ2hhbmdlRXZlbnRFbmFibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gKCF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5nZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlcG9ydCA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBpbml0V2ViUnRjUGVlclNlbmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5pc1NlbmRWaWRlbygpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnXG4gICAgICAgICAgICAgICAgICAgICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW8gPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID0gKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykgPyAnQ1VTVE9NJyA6ICh0aGlzLmlzU2VuZFNjcmVlbigpID8gJ1NDUkVFTicgOiAnQ0FNRVJBJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdwdWJsaXNoVmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtLFxuICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlclxuICAgICAgICAgICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIucHJvY2Vzc0Fuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIsIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIidQdWJsaXNoZXInIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKS50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sob2ZmZXIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyUmVjZWl2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIHNpbXVsY2FzdDogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvICdcbiAgICAgICAgICAgICAgICAgICAgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3JlY2VpdmVWaWRlb0Zyb20nLCB7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcjogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igb24gcmVjdlZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW9zIElvbmljLiBMaW1pdGF0aW9uOiBzb21lIGJ1ZyBpbiBpb3NydGMgY29yZG92YSBwbHVnaW4gbWFrZXMgaXQgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhZGQgYSB0aW1lb3V0IGJlZm9yZSBjYWxsaW5nIFBlZXJDb25uZWN0aW9uI3NldFJlbW90ZURlc2NyaXB0aW9uIGR1cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZSB0aW1lICg0MDAgbXMpIGZyb20gdGhlIG1vbWVudCBmaXJzdCBzdWJzY3JpYmVyIHN0cmVhbSBpcyByZWNlaXZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0ZpcnN0SW9uaWNJb3NTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmlzRmlyc3RJb25pY0lvc1N1YnNjcmliZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWZ0ZXIgNDAwIG1zIElvbmljIGlPUyBzdWJzY3JpYmVycyB3b24ndCBuZWVkIHRvIHJ1blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWVyQ29ubmVjdGlvbiNzZXRSZW1vdGVEZXNjcmlwdGlvbiBhZnRlciAyNTAgbXMgdGltZW91dCBhbnltb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlciA9IHRoaXMuc2Vzc2lvbi5jb3VudERvd25Gb3JJb25pY0lvc1N1YnNjcmliZXJzQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLnByb2Nlc3NBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyLCBuZWVkc1RpbWVvdXRPblByb2Nlc3NBbnN3ZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmdlbmVyYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICBjb25zdCBwYzE6IGFueSA9IHRoaXMud2ViUnRjUGVlci5wYztcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBwYzEuZ2V0UmVtb3RlU3RyZWFtcygpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgICAgIGZvciAocmVjZWl2ZXIgb2YgdGhpcy53ZWJSdGNQZWVyLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlciBpbnN0YW5jZW9mIFN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvIGFuZCBTdWJzY3JpYmVyUHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSAhISgoPFN1YnNjcmliZXI+dGhpcy5zdHJlYW1NYW5hZ2VyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gISEoKDxTdWJzY3JpYmVyPnRoaXMuc3RyZWFtTWFuYWdlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb1ZpZGVvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGxheU15UmVtb3RlKCkgJiYgISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gJiYgdGhpcy5zZXNzaW9uLnNwZWFraW5nRXZlbnRzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlU3BlYWtpbmdFdmVudHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJyA/XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKS5mb3JFYWNoKHNlbmRlciA9PiBzZW5kZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSAocmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xKSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFJlY2VpdmVycygpLmZvckVhY2gocmVjZWl2ZXIgPT4gcmVjZWl2ZXIuZ2V0U3RhdHMoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKHJlcG9ydCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IChyZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEpID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSB8fFxuICAgICAgICAgICAgcmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMCk7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlciBpbXBsZW1lbnRzIEV2ZW50RGlzcGF0Y2hlciB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpcnN0VmlkZW9FbGVtZW50OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8uc2V0QXR0cmlidXRlKCdwbGF5c2lubGluZScsICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIllvdXIgbG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICddIHZpZGVvIGlzIG5vdyBwbGF5aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZW1vdGVWaWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAncmVtb3RlVmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJ10gdmlkZW8gaXMgbm93IHBsYXlpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb24odHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgdGhpcy5lZS5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYW5kbGVyKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycgfHwgdHlwZSA9PT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1swXSAmJiB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvUGxheWluZycpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScgJiYgdGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogU3RyZWFtTWFuYWdlciB7XG4gICAgICAgIHRoaXMuZWUub25jZSh0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJyB8fCB0eXBlID09PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zWzBdICYmIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb1BsYXlpbmcnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9QbGF5aW5nJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJyAmJiB0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZVZvbHVtZUNoYW5nZUV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IHN0cmluZywgaGFuZGxlcj86IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBTdHJlYW1NYW5hZ2VyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVWb2x1bWVDaGFuZ2VFdmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2RvY3MvaG93LWRvLWkvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbCgpICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSB2aWRlbyBlbGVtZW50IGlzIGFscmVhZHkgcGFydCBvZiB0aGlzIFN0cmVhbU1hbmFnZXIgZG8gbm90aGluZ1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy52aWRlb3MpIHtcbiAgICAgICAgICAgIGlmICh2LnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldHVybk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzdHJlYW1NYW5hZ2VyIG9mIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMpIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW1NYW5hZ2VyLmRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgIHJldHVybk51bWJlciA9IC0xO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5mb3JFYWNoKHN0cmVhbU1hbmFnZXIgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknKSB7XG4gICAgICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmlkZW8uaWQpIHtcbiAgICAgICAgICAgIHZpZGVvLmlkID0gKHRoaXMucmVtb3RlID8gJ3JlbW90ZS0nIDogJ2xvY2FsLScpICsgJ3ZpZGVvLScgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZDtcbiAgICAgICAgICAgIC8vIERFUFJFQ0FURUQgcHJvcGVydHk6IGFzc2lnbiBvbmNlIHRoZSBwcm9wZXJ0eSBpZCBpZiB0aGUgdXNlciBwcm92aWRlZCBhIHZhbGlkIHRhcmdldEVsZW1lbnRcdFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknICYmICF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgcm90YXRlZCBhbmQgbm93IGlzIHNldCB0byBub3QgbWlycm9yXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNaXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvciAmJiAhdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVBbGxWaWRlb3MoKTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vyc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKHYgPT4gIXYudGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhc3NvY2lhdGVWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgZGlzYXNzb2NpYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlkZW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlb3NbaV0udmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbaV0udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgZGlzYXNzb2NpYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoKCEhdGhpcy52aWRlb3NbMF0pICYmICghIXRoaXMudmlkZW9zWzBdLnZpZGVvKSAmJiAoIXRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIHRoaXMuY2FuUGxheUxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB1cGRhdGVNZWRpYVN0cmVhbShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb3MuZm9yRWFjaChzdHJlYW1NYW5hZ2VyVmlkZW8gPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbyk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTogdm9pZCB7XG4gICAgICAgIHZpZGVvLnN0eWxlLnRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd1bnNldCc7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5cblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgU3RyZWFtTWFuYWdlciB7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBpcyBub3Qgc3VwcG9ydGVkIGJ5IE9wZW5WaWR1LlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FDQ0VTU19ERU5JRUQgPSAnREVWSUNFX0FDQ0VTU19ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSBpcyBwcm9iYWJseSBiZWluZyB1c2VkIGJ5IG90aGVyIHByb2Nlc3Mgd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgaXQuXG4gICAgICogQWNjdXJhY3kgb2YgdGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGdyYW50ZWQgZm9yIENocm9tZSBhbmQgRmlyZWZveCBjbGllbnRzLiBcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gXCJERVZJQ0VfQUxSRUFEWV9JTl9VU0VcIixcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaXMgaW5zdGFsbGVkIGJ1dCBpcyBkaXNhYmxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dXG4gICAgICovXG4gICAgUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1IgPSAnUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0cmllZCB0byBjYWxsIGEgbWV0aG9kIHdpdGhvdXQgdGhlIHJlcXVpcmVkIHBlcm1pc3Npb25zLiBUaGlzIGNhbiBvY2N1ciBmb3IgbWV0aG9kcyBbW1Nlc3Npb24ucHVibGlzaF1dLFxuICAgICAqIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dLCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV0sIFtbU3RyZWFtLmFwcGx5RmlsdGVyXV0sIFtbU3RyZWFtLnJlbW92ZUZpbHRlcl1dXG4gICAgICovXG4gICAgT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQgPSAnT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogX05vdCBpbiB1c2UgeWV0X1xuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBfTm90IGluIHVzZSB5ZXRfXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcblxuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG5cbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhZnRlciB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIG5leHQgc2libGluZylcbiAgICAgKi9cbiAgICBBRlRFUiA9ICdBRlRFUicsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgbGFzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBBUFBFTkQgPSAnQVBQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBiZWZvcmUgdGhlIHRhcmdldCBlbGVtZW50IChhcyBwcmV2aW91cyBzaWJsaW5nKVxuICAgICAqL1xuICAgIEJFRk9SRSA9ICdCRUZPUkUnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGZpcnN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFBSRVBFTkQgPSAnUFJFUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gcmVwbGFjZXMgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBSRVBMQUNFID0gJ1JFUExBQ0UnXG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgY29ubmVjdGlvbkNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGBjb25uZWN0aW9uRGVzdHJveWVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFdlYlJUQ1BlZXIgY29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBXZWJSVENQZWVyIGNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciwgZWl0aGVyIGJ5IHBhc3NpbmcgYSB2YWxpZCBwYXJhbWV0ZXIgYXMgYHRhcmdldEVsZW1lbnRgIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gb3JcbiAgICAgKiBieSBjYWxsaW5nIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgICAgICB0aGlzLmNhbGxEZWZhdWx0QmVoYXZpb3IgPSAoKSA9PiB7IH07XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG5cbi8qKlxuICogRGVmaW5lcyBldmVyeSBldmVudCBkaXNwYXRjaGVkIGJ5IGF1ZGlvL3ZpZGVvIHN0cmVhbSBmaWx0ZXJzLiBZb3UgY2FuIHN1YnNjcmliZSB0byBmaWx0ZXIgZXZlbnRzIGJ5IGNhbGxpbmcgW1tGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIERhdGEgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgZGF0YTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogRmlsdGVyLCBldmVudFR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIGV2ZW50VHlwZSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgcHVibGlzaGVyU3RhcnRTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2A6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqXG4gKiBNb3JlIGluZm9ybWF0aW9uOlxuICogLSBUaGlzIGV2ZW50cyB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGZvciAqKnJlbW90ZSBzdHJlYW1zIHRoYXQgaGF2ZSBhdWRpbyB0cmFja3MqKiAoW1tTdHJlYW0uaGFzQXVkaW9dXSBtdXN0IGJlIHRydWUpXG4gKiAtIEJvdGggZXZlbnRzIHNoYXJlIHRoZSBzYW1lIGxpZmVjeWNsZS4gVGhhdCBtZWFucyB0aGF0IHlvdSBjYW4gc3Vic2NyaWJlIHRvIG9ubHkgb25lIG9mIHRoZW0gaWYgeW91IHdhbnQsIGJ1dCBpZiB5b3UgY2FsbCBgU2Vzc2lvbi5vZmYoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpYCxcbiAqIGtlZXAgaW4gbWluZCB0aGF0IHRoaXMgd2lsbCBhbHNvIGludGVybmFsbHkgcmVtb3ZlIGFueSAncHVibGlzaGVyU3RhcnRTcGVha2luZycgZXZlbnRcbiAqIC0gWW91IGNhbiBmdXJ0aGVyIGNvbmZpZ3VyZSBob3cgdGhlIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBzZXR0aW5nIHByb3BlcnR5IGBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNgIGluIHRoZSBjYWxsIG9mIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc3RhcnRlZCBvciBzdG9wcGVkIHNwZWFraW5nXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlYW1JZCBvZiB0aGUgU3RyZWFtIGFmZmVjdGVkIGJ5IHRoZSBzcGVha2luZyBldmVudFxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHJlY29yZGluZ1N0YXJ0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKiAtIGByZWNvcmRpbmdTdG9wcGVkYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKGh0dHBzOi8vb3BlbnZpZHUuaW8vZG9jcy9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm1lZGlhU2VydmVyRGlzY29ubmVjdFwiOiBPcGVuVmlkdSBNZWRpYSBTZXJ2ZXIgaGFzIGNyYXNoZWQgb3IgbG9zdCBpdHMgY29ubmVjdGlvbi4gQSBuZXcgbWVkaWEgc2VydmVyIGluc3RhbmNlIGlzIGFjdGl2ZSBhbmQgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBzdG9wcGVkIChubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG5ldyBtZWRpYSBzZXJ2ZXIpXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgaWYgKG5hbWUgIT09IGlkKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBpbiBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zW2Nvbm5lY3Rpb25JZF0uc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkW3Nlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5zdHJlYW0uc3RyZWFtSWRdO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnNbY29ubmVjdGlvbklkXS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1tjb25uZWN0aW9uSWRdO1xuICAgICAgICB9XG4gICAgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHNpZ25hbGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV1cbiAqIC0gYHNpZ25hbDpUWVBFYDogZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBzaWduYWwgKGNhbiBiZSBlbXB0eSkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byByZWNlaXZlIHRoaXMgb2JqZWN0IGluIHRoZSBjYWxsYmFjay5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHR5cGVzIG9mIHNpZ25hbHMuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtdHB5KVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBmcm9tOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGZyb206IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuXG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIGFuZCBbW1B1Ymxpc2hlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIFN0cmVhbSBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEZvciAnc3RyZWFtRGVzdHJveWVkJyBldmVudDpcbiAgICAgKiAtIFwidW5wdWJsaXNoXCI6IG1ldGhvZCBgU2Vzc2lvbi51bnB1Ymxpc2goKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogbWV0aG9kIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWAgaGFzIGJlZW4gY2FsbGVkXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlVW5wdWJsaXNoKClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgIG92ZXIgdGhlIFN0cmVhbVxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5U2VydmVyXCI6IHRoZSB1c2VyJ3Mgc3RyZWFtIGhhcyBiZWVuIHVucHVibGlzaGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHVzZXIncyBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibWVkaWFTZXJ2ZXJEaXNjb25uZWN0XCI6IE9wZW5WaWR1IE1lZGlhIFNlcnZlciBoYXMgY3Jhc2hlZCBvciBsb3N0IGl0cyBjb25uZWN0aW9uLiBBIG5ldyBtZWRpYSBzZXJ2ZXIgaW5zdGFuY2UgaXMgYWN0aXZlIGFuZCBubyBtZWRpYSBzdHJlYW1zIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1lZGlhIHNlcnZlclxuICAgICAqXG4gICAgICogRm9yICdzdHJlYW1DcmVhdGVkJyBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnUHVibGlzaGVyJ1wiKTtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKCg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBQdWJsaXNoZXIgb2JqZWN0IGZyb20gT3BlblZpZHUgcHVibGlzaGVycyBhcnJheVxuICAgICAgICAgICAgICAgIGNvbnN0IG9wZW52aWR1UHVibGlzaGVycyA9ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KS5vcGVudmlkdS5wdWJsaXNoZXJzO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlbnZpZHVQdWJsaXNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVudmlkdVB1Ymxpc2hlcnNbaV0gPT09ICg8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLnNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWRbdGhpcy5zdHJlYW0uc3RyZWFtSWRdO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9uc1t0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5vcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ub3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgc3RyZWFtUGxheWluZ2A6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuZXZlciBpdHMgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nIChvbmUgb2YgaXRzIHZpZGVvcyBoYXMgbWVkaWFcbiAqIGFuZCBoYXMgYmVndW4gdG8gcGxheSkuIFRoaXMgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkIHdoZW4gdGhlc2UgMyBjb25kaXRpb25zIGFyZSBtZXQgMSkgVGhlIFN0cmVhbU1hbmFnZXIgaGFzIG5vIHZpZGVvIGFzc29jaWF0ZWQgaW4gdGhlIERPTSAyKSBJdCBpcyBhc3NvY2lhdGVkIHRvIG9uZSB2aWRlbyAzKSBUaGF0IHZpZGVvIHN0YXJ0cyBwbGF5aW5nXG4gKiAtIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWA6IGRpc3BhdGNoZWQgYnkgW1tTdHJlYW1NYW5hZ2VyXV0gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKSB3aGVuIHRoZSB2b2x1bWUgb2YgaXRzIFN0cmVhbSdzIGF1ZGlvIHRyYWNrXG4gKiBjaGFuZ2VzLiBPbmx5IGFwcGxpZXMgaWYgW1tTdHJlYW0uaGFzQXVkaW9dXSBpcyBgdHJ1ZWAuIFRoZSBmcmVxdWVuY3kgdGhpcyBldmVudCBpcyBmaXJlZCB3aXRoIGlzIGRlZmluZWQgYnkgcHJvcGVydHkgYGludGVydmFsYCBvZlxuICogW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnNdXSAoZGVmYXVsdCA1MG1zKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZWAgZXZlbnQ6XG4gICAgICogLSBge25ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXJ9YDogbmV3IGFuZCBvbGQgYXVkaW8gdm9sdW1lIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBiZXR3ZWVuIC0xMDAgKHNpbGVuY2UpIGFuZCAwIChsb3VkZXN0IHBvc3NpYmxlIHZvbHVtZSkuXG4gICAgICogVGhleSBhcmUgbm90IGV4YWN0IGFuZCBkZXBlbmQgb24gaG93IHRoZSBicm93c2VyIGlzIG1hbmFnaW5nIHRoZSBhdWRpbyB0cmFjaywgYnV0IC0xMDAgYW5kIDAgY2FuIGJlIHRha2VuIGFzIGxpbWl0IHZhbHVlcy5cbiAgICAgKiBcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxuXG59IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZW50IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gYXMgd2VsbCBhcyBieSBbW1N0cmVhbU1hbmFnZXJdXSAoW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0pLlxuICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFueSByZW1vdGUgc3RyZWFtIChvd25lZCBieSBhIFN1YnNjcmliZXIpIG9yIGxvY2FsIHN0cmVhbSAob3duZWQgYnkgYSBQdWJsaXNoZXIpIHVuZGVyZ29lc1xuICogYW55IGNoYW5nZSBpbiBhbnkgb2YgaXRzIG11dGFibGUgcHJvcGVydGllcyAoc2VlIFtbY2hhbmdlZFByb3BlcnR5XV0pLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgIG9yIGBcInNjcmVlblJlc2l6ZWRcImBcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciwgc3RyZWFtOiBTdHJlYW0sIGNoYW5nZWRQcm9wZXJ0eTogc3RyaW5nLCBuZXdWYWx1ZTogT2JqZWN0LCBvbGRWYWx1ZTogT2JqZWN0LCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG5cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMTkgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogLSBgdmlkZW9FbGVtZW50Q3JlYXRlZGA6IGRpc3BhdGNoZWQgYnkgW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gd2hlbmV2ZXIgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGluc2VydGVkIGludG8gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS4gU2VlXG4gKiBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9kb2NzL2hvdy1kby1pL21hbmFnZS12aWRlb3MpIHNlY3Rpb24uXG4gKiAtIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIHdoZW5ldmVyIGFuIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gRE9NIGJ5IE9wZW5WaWR1IEJyb3dzZXIgbGlicmFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuXG4gICAgLyoqXG4gICAgICogVmlkZW8gZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cblxufSIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICtuZXcgRGF0ZTtcbn07XG5cbnZhciBQSU5HX0lOVEVSVkFMID0gNTAwMDtcblxudmFyIFJFQ09OTkVDVElORyA9ICdSRUNPTk5FQ1RJTkcnO1xudmFyIENPTk5FQ1RFRCA9ICdDT05ORUNURUQnO1xudmFyIERJU0NPTk5FQ1RFRCA9ICdESVNDT05ORUNURUQnO1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKlxuICogaGVhcnRiZWF0OiBpbnRlcnZhbCBpbiBtcyBmb3IgZWFjaCBoZWFydGJlYXQgbWVzc2FnZSxcbiAqIHNlbmRDbG9zZU1lc3NhZ2UgOiB0cnVlIC8gZmFsc2UsIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLCBpdCBzZW5kcyBhIGNsb3NlU2Vzc2lvbiBtZXNzYWdlXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqICB1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuICogXHRvbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG4gKiBcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0IChtYXggcmV0cmllcyBmb3IgcmVjb25uZWN0aW5nIHJlYWNoZWQpLFxuICogXHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbiAqIFx0b25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxuICogXHRvbmVycm9yIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZXJlIGlzIGFuIGVycm9yXG4gKiB9LFxuICogcnBjIDoge1xuICogXHRyZXF1ZXN0VGltZW91dCA6IHRpbWVvdXQgZm9yIGEgcmVxdWVzdCxcbiAqIFx0c2Vzc2lvblN0YXR1c0NoYW5nZWQ6IGNhbGxiYWNrIG1ldGhvZCBmb3IgY2hhbmdlcyBpbiBzZXNzaW9uIHN0YXR1cyxcbiAqIFx0bWVkaWFSZW5lZ290aWF0aW9uOiBtZWRpYVJlbmVnb3RpYXRpb25cbiAqIH1cbiAqIDwvcHJlPlxuICovXG5mdW5jdGlvbiBKc29uUnBjQ2xpZW50KGNvbmZpZ3VyYXRpb24pIHtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBSRUNPTk5FQ1RJTkcgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RJTkcgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS1cIik7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25jb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tXCIpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbiAocmVxdWVzdCkge1xuXG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBjb25maWd1cmF0aW9uLnJwY1tyZXF1ZXN0Lm1ldGhvZF07XG5cbiAgICAgICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIk1ldGhvZCBcIiArIHJlcXVlc3QubWV0aG9kICsgXCIgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChtZXRob2QgIT09ICdwaW5nJykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXF1ZXN0OiBtZXRob2Q6JyArIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbiAocGluZ051bSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkVycm9yIGluIHBpbmcgcmVxdWVzdCAjXCIgKyBwaW5nTnVtICsgXCIgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlNlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICNcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmdOdW0gKyBcIi4gUmVjb25uZWN0aW5nLi4uIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkocGluZ05leHROdW0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlRyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTdGFydGluZyBwaW5nIChpZiBjb25maWd1cmVkKVwiKVxuICAgICAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHBpbmdJbnRlcnZhbCA9IHNldEludGVydmFsKHNlbmRQaW5nLCBjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCk7XG4gICAgICAgICAgICAgICAgc2VuZFBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0b3BQaW5nKCkge1xuICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgcGluZ05leHROdW0gPSAtMTtcbiAgICAgICAgcnBjLmNhbmNlbCgpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcgIHdpdGggY29kZTogXCIgKyBjb2RlICsgXCIgYmVjYXVzZTogXCIgKyByZWFzb24pO1xuXG4gICAgICAgIGlmIChwaW5nSW50ZXJ2YWwgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbGVhcmluZyBwaW5nIGludGVydmFsXCIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5zZW5kQ2xvc2VNZXNzYWdlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZW5kaW5nIGNsb3NlIG1lc3NhZ2VcIilcbiAgICAgICAgICAgIHRoaXMuc2VuZCgnY2xvc2VTZXNzaW9uJywgbnVsbCwgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICB3cy5mb3JjZUNsb3NlKG1pbGxpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiAgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTMtMjAxNSBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG52YXIgTG9nZ2VyID0gY29uc29sZTtcblxuLyoqXG4gKiBHZXQgZWl0aGVyIHRoZSBgV2ViU29ja2V0YCBvciBgTW96V2ViU29ja2V0YCBnbG9iYWxzXG4gKiBpbiB0aGUgYnJvd3NlciBvciB0cnkgdG8gcmVzb2x2ZSBXZWJTb2NrZXQtY29tcGF0aWJsZVxuICogaW50ZXJmYWNlIGV4cG9zZWQgYnkgYHdzYCBmb3IgTm9kZS1saWtlIGVudmlyb25tZW50LlxuICovXG5cbi8qdmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAgIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG59Ki9cblxuLy92YXIgU29ja0pTID0gcmVxdWlyZSgnc29ja2pzLWNsaWVudCcpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcblx0XHR1cmkgOiB3c1VyaSxcblx0XHR1c2VTb2NrSlMgOiB0cnVlICh1c2UgU29ja0pTKSAvIGZhbHNlICh1c2UgV2ViU29ja2V0KSBieSBkZWZhdWx0LFxuXHRcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcblx0XHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcblx0XHRvbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcblx0XHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG5cdH07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcblxuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgdXNlU29ja0pTID0gY29uZmlnLnVzZVNvY2tKUztcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgIHZhciB3cztcblxuICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgd3MgPSBuZXcgU29ja0pTKHdzVXJpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgIH1cblxuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKFwiQ291bGQgbm90IGNvbm5lY3QgdG8gXCIgKyB3c1VyaSArIFwiIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpXCIsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHdzVXJpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgYnkgdXNlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlY2x5LiBSZWNvbm5lY3RpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NlIGNhbGxiYWNrIGZyb20gcHJldmlvdXMgd2Vic29ja2V0LiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvU2FtZVVyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcInJlY29ubmVjdFRvU2FtZVVyaSAoYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzICsgXCIsIG1heD1cIiArIG1heFJldHJpZXMgKyBcIilcIik7XG5cbiAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIud2FybihcIlRyeWluZyB0byByZWNvbm5lY3RUb05ld1VyaSB3aGVuIHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi5cIilcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb3JjaW5nRGlzY29ubmVjdGlvbikge1xuICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25maWcubmV3V3NVcmlPblJlY29ubmVjdGlvbihmdW5jdGlvbiAoZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgbmV3V3NVcmkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb25uZWN0VG9OZXdVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcywgd3NVcmkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETyBUZXN0IHJldHJpZXMuIEhvdyB0byBmb3JjZSBub3QgY29ubmVjdGlvbj9cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCByZWNvbm5lY3RXc1VyaSkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjXCIgKyBudW1SZXRyaWVzKTtcblxuICAgICAgICB3cy5jbG9zZSgpO1xuXG4gICAgICAgIHdzVXJpID0gcmVjb25uZWN0V3NVcmkgfHwgd3NVcmk7XG5cbiAgICAgICAgdmFyIG5ld1dzO1xuICAgICAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBTb2NrSlMod3NVcmkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3V3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld1dzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGVkIGFmdGVyIFwiICsgbnVtUmV0cmllcyArIFwiIGF0dGVtcHRzLi4uXCIpO1xuICAgICAgICAgICAgbG9nQ29ubmVjdGVkKG5ld1dzLCB3c1VyaSk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3V3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIG9uRXJyb3JPckNsb3NlID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBuZXdXcy5vbmVycm9yID0gb25FcnJvck9yQ2xvc2U7XG5cbiAgICAgICAgd3MgPSBuZXdXcztcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICB9O1xuXG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24gKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogUmVjb3ZlciBnb29kIHdzVXJpIFwiICsgZ29vZFdzVXJpKTtcbiAgICAgICAgICAgICAgICB3c1VyaSA9IGdvb2RXc1VyaTtcblxuICAgICAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgIH0sIG1pbGxpcyk7XG4gICAgICAgIH1cblxuICAgICAgICB3cy5jbG9zZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdFdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RXc1wiKTtcbiAgICAgICAgcmVjb25uZWN0VG9TYW1lVXJpKE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uOyIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZVxuaWYoT2JqZWN0LmRlZmluZVByb3BlcnR5KVxue1xuICB0cnlcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgXCJ4XCIsIHt9KTtcbiAgfVxuICBjYXRjaChlKVxuICB7XG4gICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZVxuICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xuICAgIGlmICh0eXBlb2YgdGhpcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xuICAgIH1cblxuICAgIHZhciBhQXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxuICAgICAgICBmQm91bmQgID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXNcbiAgICAgICAgICAgICAgICAgPyB0aGlzXG4gICAgICAgICAgICAgICAgIDogb1RoaXMsXG4gICAgICAgICAgICAgICAgIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgIH07XG5cbiAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xuICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgcmV0dXJuIGZCb3VuZDtcbiAgfTtcbn1cblxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cblxudmFyIEJBU0VfVElNRU9VVCA9IDUwMDA7XG5cblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKVxue1xuICBpZighcmVzcG9uc2VNZXRob2RzKSByZXR1cm4ge307XG5cbiAgZm9yKHZhciBrZXkgaW4gcmVzcG9uc2VNZXRob2RzKVxuICB7XG4gICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICBpZih0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpXG4gICAgICByZXNwb25zZU1ldGhvZHNba2V5XSA9XG4gICAgICB7XG4gICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgfVxuICB9O1xuXG4gIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59O1xuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpXG57XG4gIGlmKCF0cmFuc3BvcnQpIHJldHVybjtcblxuICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4ge3NlbmQ6IHRyYW5zcG9ydH07XG5cbiAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgaWYodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuXG4gIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gIGlmKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQucG9zdE1lc3NhZ2U7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFN0cmVhbSBBUElcbiAgaWYodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC53cml0ZTtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG5cbiAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICBpZih0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUcmFuc3BvcnQgaXMgbm90IGEgZnVuY3Rpb24gbm9yIGEgdmFsaWQgb2JqZWN0XCIpO1xufTtcblxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcylcbntcbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2RcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtc1xuICB9XG4gIGVsc2VcbiAge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge3ZhbHVlOiBtZXRob2QsIGVudW1lcmFibGU6IHRydWV9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHt2YWx1ZTogcGFyYW1zLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdClcbntcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmKCFwYWNrZXIpXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgbm90IGRlZmluZWQnKTtcblxuICBpZighcGFja2VyLnBhY2sgfHwgIXBhY2tlci51bnBhY2spXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gIHZhciByZXNwb25zZU1ldGhvZHMgPSB1bmlmeVJlc3BvbnNlTWV0aG9kcyhwYWNrZXIucmVzcG9uc2VNZXRob2RzKTtcblxuXG4gIGlmKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgIG9uUmVxdWVzdCA9IG9wdGlvbnM7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIG9wdGlvbnMgICA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZihvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYodHJhbnNwb3J0ICYmICEodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnRcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZihvblJlcXVlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIGlmKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cbiAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgaWYob25SZXF1ZXN0KVxuICAgIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG5cbiAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySURcbiAgZWxzZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge3ZhbHVlOiBvcHRpb25zLnBlZXJJRH0pO1xuXG4gIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuXG4gIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpXG4gIHtcbiAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgfTtcblxuICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAge1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cbiAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbih2YWx1ZSlcbiAge1xuICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICBpZih0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICB0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuXG4gICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICBlbHNlIGlmKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFNldCBsaXN0ZW5lciBvbiBuZXcgdHJhbnNwb3J0XG4gICAgaWYodmFsdWUpXG4gICAge1xuICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgIGlmKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih2YWx1ZS5hZGRMaXN0ZW5lcilcbiAgICAgICAgdmFsdWUuYWRkTGlzdGVuZXIoJ2RhdGEnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICB9XG5cbiAgaWYoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAge1xuICAgICAgZ2V0OiB0aGlzLmdldFRyYW5zcG9ydC5iaW5kKHRoaXMpLFxuICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgfSlcblxuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG5cbiAgdmFyIHJlcXVlc3RfdGltZW91dCAgICAgID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICB2YXIgcmVzcG9uc2VfdGltZW91dCAgICAgPSBvcHRpb25zLnJlc3BvbnNlX3RpbWVvdXQgICAgIHx8IEJBU0VfVElNRU9VVDtcbiAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCAgID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgICB8fCBCQVNFX1RJTUVPVVQ7XG5cblxuICB2YXIgcmVxdWVzdElEID0gMDtcblxuICB2YXIgcmVxdWVzdHMgID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgZHVwbGljYXRlIHJlcXVlc3QgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpXG4gIHtcbiAgICB2YXIgcmVzcG9uc2UgPVxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAvKiogVGltZW91dCB0byBhdXRvLWNsZWFuIG9sZCByZXNwb25zZXMgKi9cbiAgICAgIHRpbWVvdXQ6IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgICAge1xuICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgIH0sXG4gICAgICByZXNwb25zZV90aW1lb3V0KVxuICAgIH07XG5cbiAgICByZXNwb25zZXMuc2V0KHJlc3BvbnNlLCBpZCwgZGVzdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgKi9cbiAgZnVuY3Rpb24gc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pXG4gIHtcbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5yZW1vdmUoYWNrLCBmcm9tKTtcbiAgICB9LFxuICAgIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICBwcm9jZXNzZWRSZXNwb25zZXMuc2V0KHRpbWVvdXQsIGFjaywgZnJvbSk7XG4gIH07XG5cblxuICAvKipcbiAgICogUmVwcmVzZW50YXRpb24gb2YgYSBSUEMgcmVxdWVzdFxuICAgKlxuICAgKiBAY2xhc3NcbiAgICogQGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBpZGVudGlmaWVyIG9mIHRoZSByZXF1ZXN0XG4gICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWQsIGZyb20sIHRyYW5zcG9ydClcbiAge1xuICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gICAge1xuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH1cblxuICAgIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsXG4gICAgICB7XG4gICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICB9KVxuXG4gICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgKi9cbiAgICBpZighKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSlcbiAgICB7XG4gICAgICBpZihkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kID0gcmVzcG9uc2VNZXRob2RzW21ldGhvZF07XG5cbiAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycm9yXVxuICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uKGVycm9yLCByZXN1bHQsIHRyYW5zcG9ydClcbiAgICB7XG4gICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgaWYoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCBlcnJvciAmJiBlcnJvci5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICB7XG4gICAgICAgIGlmKHJlc3VsdCAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSBlcnJvcjtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGVsc2UgaWYocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb25cbiAgICAgIHx8IHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgLy8gRHVwbGljYXRlZCByZXF1ZXN0LCByZW1vdmUgb2xkIHJlc3BvbnNlIHRpbWVvdXRcbiAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgIGlmKGZyb20gIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICBpZihyZXN1bHQpXG4gICAgICAgICAgcmVzdWx0LmRlc3QgPSBmcm9tO1xuICAgICAgfTtcblxuICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICBpZihlcnJvciB8fCByZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAge1xuICAgICAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHtcbiAgICAgICAgICBpZihlcnJvcilcbiAgICAgICAgICAgIGVycm9yLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXN1bHQuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kKVxuICAgICAgICB7XG4gICAgICAgICAgaWYocmVzcG9uc2VNZXRob2QuZXJyb3IgPT0gdW5kZWZpbmVkICYmIGVycm9yKVxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgPyByZXNwb25zZU1ldGhvZC5lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICBlcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgfTtcblxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICBlbHNlIGlmKHJlc3BvbnNlKVxuICAgICAgICBtZXNzYWdlID0gcmVzcG9uc2UubWVzc2FnZTtcblxuICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayh7cmVzdWx0OiBudWxsfSwgaWQpO1xuXG4gICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cbiAgfTtcbiAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuXG4gIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKVxuICB7XG4gICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgIGlmKCFrZXkpIHJldHVybjtcblxuICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMucG9wKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIGlmKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICBjbGVhclRpbWVvdXQocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAqXG4gICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICovXG4gIHRoaXMuY2FuY2VsID0gZnVuY3Rpb24obWVzc2FnZSlcbiAge1xuICAgIGlmKG1lc3NhZ2UpIHJldHVybiBjYW5jZWwobWVzc2FnZSk7XG5cbiAgICBmb3IodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpXG4gICAgICBjYW5jZWwobWVzc2FnZSk7XG4gIH07XG5cblxuICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKVxuICB7XG4gICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpXG4gICAgICB0cmFuc3BvcnQuY2xvc2UoNDAwMywgXCJDYW5jZWwgcmVxdWVzdFwiKTtcblxuICAgIC8vIFJlcXVlc3QgJiBwcm9jZXNzZWQgcmVzcG9uc2VzXG4gICAgdGhpcy5jYW5jZWwoKTtcblxuICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAvLyBSZXNwb25zZXNcbiAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbihyZXNwb25zZSlcbiAgICB7XG4gICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG4gICAgfSk7XG4gIH07XG5cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdIC0gdHJhbnNwb3J0IHdoZXJlIHRvIHNlbmQgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAqL1xuICB0aGlzLmVuY29kZSA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKVxuICB7XG4gICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICBpZihwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gcGFyYW1zO1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgZGVzdCAgICAgID0gdW5kZWZpbmVkO1xuICAgICAgcGFyYW1zICAgID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGVsc2UgaWYoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKHRyYW5zcG9ydCAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IGRlc3Q7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZih0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICB7XG4gICAgICBpZihjYWxsYmFjayAhPSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgIGNhbGxiYWNrICA9IHRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICB9O1xuXG4gICAgaWYoZGVzdCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgfTtcblxuICAgIC8vIEVuY29kZSBtZXNzYWdlXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICB9O1xuXG4gICAgaWYoY2FsbGJhY2spXG4gICAge1xuICAgICAgdmFyIGlkID0gcmVxdWVzdElEKys7XG4gICAgICB2YXIgcmV0cmllZCA9IDA7XG5cbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlLCBpZCk7XG5cbiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IsIHJlc3VsdClcbiAgICAgIHtcbiAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgcmVxdWVzdCA9XG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6ICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgY2FsbGJhY2s6ICAgICAgICBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJ0ID0gKG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQpO1xuICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0Kk1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICBtZXNzYWdlMktleVttZXNzYWdlXSA9IHtpZDogaWQsIGRlc3Q6IGRlc3R9O1xuICAgICAgICByZXF1ZXN0cy5zZXQocmVxdWVzdCwgaWQsIGRlc3QpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpXG4gICAgICB7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQrJyByZXRyeSBmb3IgcmVxdWVzdCBtZXNzYWdlOicsbWVzc2FnZSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXQgPSBwcm9jZXNzZWRSZXNwb25zZXMucG9wKGlkLCBkZXN0KTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgfTtcblxuICAgICAgZnVuY3Rpb24gdGltZW91dCgpXG4gICAgICB7XG4gICAgICAgIGlmKHJldHJpZWQgPCBtYXhfcmV0cmllcylcbiAgICAgICAgICByZXR1cm4gcmV0cnkodHJhbnNwb3J0KTtcblxuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgZXJyb3IucmVxdWVzdCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgfTtcblxuICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSk7XG5cbiAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQpXG4gICAgICByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfTtcblxuICAvKipcbiAgICogRGVjb2RlIGFuZCBwcm9jZXNzIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAqXG4gICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgKiAgIGB1bmRlZmluZWRgIHRvIG5vdGlmeSB0aGF0IGl0IHdhcyBwcm9jZXNzZWRcbiAgICpcbiAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICovXG4gIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24obWVzc2FnZSwgdHJhbnNwb3J0KVxuICB7XG4gICAgaWYoIW1lc3NhZ2UpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWVzc2FnZSBpcyBub3QgZGVmaW5lZFwiKTtcblxuICAgIHRyeVxuICAgIHtcbiAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBjYXRjaChlKVxuICAgIHtcbiAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdmFyIGlkICAgICA9IG1lc3NhZ2UuaWQ7XG4gICAgdmFyIGFjayAgICA9IG1lc3NhZ2UuYWNrO1xuICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICB2YXIgZnJvbSA9IHBhcmFtcy5mcm9tO1xuICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgIGlmKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBOb3RpZmljYXRpb25cbiAgICBpZihpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgIGlmKHNlbGYuZW1pdCgncmVxdWVzdCcsIG5vdGlmaWNhdGlvbikpIHJldHVybjtcbiAgICAgIHJldHVybiBub3RpZmljYXRpb247XG4gICAgfTtcblxuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKVxuICAgIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0cmFuc3BvcnQgYW5kIGl0J3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QsIHJlcGx5IGlubWVkaWF0bHlcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgIGlmKHJlc3BvbnNlKVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBpZEFjayA9IChpZCAhPSB1bmRlZmluZWQpID8gaWQgOiBhY2s7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZEFjaywgZnJvbSwgdHJhbnNwb3J0KTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dClcbiAgICB7XG4gICAgICBjb25zb2xlLndhcm4oXCJSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZFwiLCBtZXNzYWdlKTtcblxuICAgICAgLy8gVXBkYXRlIGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKTtcbiAgICB9O1xuXG5cbiAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICBpZihtZXRob2QpXG4gICAge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgaWYoZGVzdCA9PSB1bmRlZmluZWQgfHwgZGVzdCA9PSBzZWxmLnBlZXJJRClcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYocmVxdWVzdClcbiAgICAgICAge1xuICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIHBhcmFtcyk7XG5cbiAgICAgICAgICBpZihtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXF1ZXN0XG4gICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdmFyIGVycm9yICA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgLy8gSWdub3JlIHJlc3BvbnNlcyBub3Qgc2VuZCB0byB1c1xuICAgIGlmKGVycm9yICAmJiBlcnJvci5kZXN0ICAmJiBlcnJvci5kZXN0ICAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgIGlmKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgIGlmKCFyZXF1ZXN0KVxuICAgIHtcbiAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICBpZihwcm9jZXNzZWQpXG4gICAgICAgIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihcIk5vIGNhbGxiYWNrIHdhcyBkZWZpbmVkIGZvciB0aGlzIG1lc3NhZ2VcIiwgbWVzc2FnZSk7XG4gICAgfTtcblxuICAgIC8vIFByb2Nlc3MgcmVzcG9uc2VcbiAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gIH07XG59O1xuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuXG5ScGNCdWlsZGVyLlJwY05vdGlmaWNhdGlvbiA9IFJwY05vdGlmaWNhdGlvbjtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZClcbntcbiAgdmFyIHJlc3VsdCA9XG4gIHtcbiAgICBqc29ucnBjOiBcIjIuMFwiXG4gIH07XG5cbiAgLy8gUmVxdWVzdFxuICBpZihtZXNzYWdlLm1ldGhvZClcbiAge1xuICAgIHJlc3VsdC5tZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcblxuICAgIGlmKG1lc3NhZ2UucGFyYW1zKVxuICAgICAgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgIGlmKGlkICE9IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9XG5cbiAgLy8gUmVzcG9uc2VcbiAgZWxzZSBpZihpZCAhPSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihtZXNzYWdlLmVycm9yKVxuICAgIHtcbiAgICAgIGlmKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWRcIik7XG5cbiAgICAgIHJlc3VsdC5lcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgfVxuICAgIGVsc2UgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWRcIik7XG5cbiAgICByZXN1bHQuaWQgPSBpZDtcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn07XG5cbi8qKlxuICogVW5wYWNrIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSW52YWxpZCBKc29uUlBDIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gb2JqZWN0IGZpbGxlZCB3aXRoIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gdW5wYWNrKG1lc3NhZ2UpXG57XG4gIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gIGlmKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGl0J3MgYSB2YWxpZCBtZXNzYWdlXG5cbiAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgaWYodmVyc2lvbiAhPT0gJzIuMCcpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgSnNvblJQQyB2ZXJzaW9uICdcIiArIHZlcnNpb24gKyBcIic6IFwiICsgbWVzc2FnZSk7XG5cbiAgLy8gUmVzcG9uc2VcbiAgaWYocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpXG4gIHtcbiAgICBpZihyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgbWVzc2FnZTogXCIrbWVzc2FnZSk7XG5cbiAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGVycm9yX2RlZmluZWQgID0gcmVzdWx0LmVycm9yICAhPT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgIGlmKHJlc3VsdF9kZWZpbmVkICYmIGVycm9yX2RlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIGlmKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogXCIrbWVzc2FnZSk7XG5cbiAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gdW5wYWNrZWQgbWVzc2FnZVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG5leHBvcnRzLnBhY2sgICA9IHBhY2s7XG5leHBvcnRzLnVucGFjayA9IHVucGFjaztcbiIsImZ1bmN0aW9uIHBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vdCB5ZXQgaW1wbGVtZW50ZWRcIik7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgID0gcmVxdWlyZSgnLi9YbWxSUEMnKTtcblxuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgID0gWG1sUlBDO1xuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG4gICAgXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxud2luZG93LmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQgPT09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soJ3Blcm1pc3Npb24tZGVuaWVkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCwgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldFNvdXJjZUlkTWVzc2FnZSwgMTAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHdpbmRvdy5zY3JlZW4ud2lkdGggPiAxOTIwID8gd2luZG93LnNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiB3aW5kb3cuc2NyZWVuLmhlaWdodCA+IDEwODAgPyB3aW5kb3cuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbiAgICBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgfSwgJyonKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbzogdHJ1ZVxuICAgICAgICB9LCAnKicpO1xuICAgIH1cbn1cblxudmFyIGlmcmFtZTtcblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIFJUQ011bHRpQ29ubmVjdGlvbiB2M1xud2luZG93LmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbndpbmRvdy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM6IHRydWVcbiAgICB9LCAnKicpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2V0U2NyZWVuSWQ7IiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG52YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaXNPcGVyYSA9ICEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwO1xudmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5vcmlnaW4gIT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIG9uTWVzc2FnZUNhbGxiYWNrKGV2ZW50LmRhdGEpO1xufSk7XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaylcbiAgICAgICAgICAgIHJldHVybiBzY3JlZW5DYWxsYmFjaygnUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjayhzb3VyY2VJZCA9IGRhdGEuc291cmNlSWQsIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgICdnZXQtY3VzdG9tLXNvdXJjZUlkJzogYXJyXG4gICAgfSwgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpXG4gICAgICAgIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveClcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiIFxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDE5IE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB1dWlkID0gcmVxdWlyZSgndXVpZCcpO1xuaW1wb3J0IHBsYXRmb3JtID0gcmVxdWlyZSgncGxhdGZvcm0nKTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbixcbiAgICAgICAgdmlkZW86IGJvb2xlYW5cbiAgICB9O1xuICAgIHNpbXVsY2FzdDogYm9vbGVhbjtcbiAgICBvbmljZWNhbmRpZGF0ZTogKGV2ZW50KSA9PiB2b2lkO1xuICAgIGljZVNlcnZlcnM6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW07XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXIge1xuXG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9ICghIXRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzICYmIHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDApID8gdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCk7XG5cbiAgICAgICAgdGhpcy5wYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbih7IGljZVNlcnZlcnM6IHRoaXMuY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzIH0pO1xuICAgICAgICB0aGlzLmlkID0gISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHV1aWQudjQoKTtcblxuICAgICAgICB0aGlzLnBjLm9uaWNlY2FuZGlkYXRlID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQuY2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUgPSBldmVudC5jYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goPFJUQ0ljZUNhbmRpZGF0ZT57IGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbmljZWNhbmRpZGF0ZShldmVudC5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBjLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRJY2VDYW5kaWRhdGUoPFJUQ0ljZUNhbmRpZGF0ZT50aGlzLmljZUNhbmRpZGF0ZUxpc3Quc2hpZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgICAqIHByb3BlcnRpZXMgcmVjZWl2ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBJdCBzdGFydHMgdGhlIFNEUCBuZWdvdGlhdGlvblxuICAgICAqIHByb2Nlc3M6IGdlbmVyYXRlcyB0aGUgU0RQIG9mZmVyIGFuZCBpbnZva2VzIHRoZSBvbnNkcG9mZmVyIGNhbGxiYWNrLiBUaGlzXG4gICAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAgICogYW5zd2VyIGZyb20gYW5vdGhlciBwZWVyLlxuICAgICAqL1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1RoZSBwZWVyIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGluIFwiY2xvc2VkXCIgc3RhdGUuIFRoaXMgaXMgbW9zdCBsaWtlbHkgZHVlIHRvIGFuIGludm9jYXRpb24gb2YgdGhlIGRpc3Bvc2UgbWV0aG9kIGJlZm9yZSBhY2NlcHRpbmcgaW4gdGhlIGRpYWxvZ3VlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm1bJ2lzSW9uaWNJb3MnXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgdXNlIGRlcHJlY2F0ZWQgV2ViUlRDIEFQSVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYzI6IGFueSA9IHRoaXMucGM7XG4gICAgICAgICAgICAgICAgICAgIHBjMi5hZGRTdHJlYW0odGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSh2aWRlb1NvdXJjZUlzTWVkaWFTdHJlYW1UcmFjazogYm9vbGVhbikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybVsnaXNJb25pY0lvcyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCB1c2UgZGVwcmVjYXRlZCBXZWJSVEMgQVBJXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3Agc2VuZGVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBjMTogYW55ID0gdGhpcy5wYztcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgcGMxLmdldExvY2FsU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZpZGVvU291cmNlSXNNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBjMS5yZW1vdmVTdHJlYW0oc2VuZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHJlY2VpdmVycyBkZXByZWNhdGVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZWl2ZXIgb2YgcGMxLmdldFJlbW90ZVN0cmVhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHNlbmRlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZW5kZXIgb2YgdGhpcy5wYy5nZXRTZW5kZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlkZW9Tb3VyY2VJc01lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFzZW5kZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCByZWNlaXZlcnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlaXZlciBvZiB0aGlzLnBjLmdldFJlY2VpdmVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZWNlaXZlci50cmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLnRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBkaXNwb3Npbmcgd2VicnRjIHBlZXIgJyArIGVycik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gb2ZmZXIsIHNldHMgaXQgYXMgbG9jYWwgZGVzY3JpcHRpb24gYW5kIHJldHVybnMgdGhlIG9mZmVyIHBhcmFtXG4gICAgICogdG8gc2VuZCB0byBPcGVuVmlkdSBTZXJ2ZXIgKHdpbGwgYmUgdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBvZiBvdGhlciBwZWVyKVxuICAgICAqL1xuICAgIGdlbmVyYXRlT2ZmZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLCBvZmZlclZpZGVvID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSAodHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicpID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86ICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBvZmZlckF1ZGlvKSxcbiAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiAodGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JUQ1BlZXJDb25uZWN0aW9uIGNvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUgPT09ICdTYWZhcmknICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIChleGNsdWRpbmcgSW9uaWMpLCBhdCBsZWFzdCBvbiBpT1MganVzdCBzZWVtcyB0byBzdXBwb3J0IHVuaWZpZWQgcGxhbiwgd2hlcmVhcyBpbiBvdGhlciBicm93c2VycyBpcyBub3QgeWV0IHJlYWR5IGFuZCBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbFxuICAgICAgICAgICAgICAgIGlmIChvZmZlckF1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIoJ2F1ZGlvJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG9mZmVyVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcigndmlkZW8nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG9mZmVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4ob2ZmZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdDcmVhdGVkIFNEUCBvZmZlcicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbERlc2NyaXB0aW9uID0gdGhpcy5wYy5sb2NhbERlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ0xvY2FsIGRlc2NyaXB0aW9uIHNldCcsIGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCdMb2NhbCBkZXNjcmlwdGlvbiBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIGludm9rZWQgd2hlbiBhIFNEUCBhbnN3ZXIgaXMgcmVjZWl2ZWQuIEZpbmFsIHN0ZXAgaW4gU0RQIG5lZ290aWF0aW9uLCB0aGUgcGVlclxuICAgICAqIGp1c3QgbmVlZHMgdG8gc2V0IHRoZSBhbnN3ZXIgYXMgaXRzIHJlbW90ZSBkZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHByb2Nlc3NBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcsIG5lZWRzVGltZW91dE9uUHJvY2Vzc0Fuc3dlcjogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdTRFAgYW5zd2VyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtWydpc0lvbmljSW9zJ10pIHtcbiAgICAgICAgICAgICAgICAvLyBJb25pYyBpT1MgcGxhdGZvcm1cbiAgICAgICAgICAgICAgICBpZiAobmVlZHNUaW1lb3V0T25Qcm9jZXNzQW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDQwMCBtcyBoYXZlIG5vdCBlbGFwc2VkIHlldCBzaW5jZSBmaXJzdCByZW1vdGUgc3RyZWFtIHRyaWdnZXJlZCBTdHJlYW0jaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKCdzZXRSZW1vdGVEZXNjcmlwdGlvbiBydW4gYWZ0ZXIgdGltZW91dCBmb3IgSW9uaWMgaU9TIGRldmljZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKGFuc3dlcikpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyA0MDAgbXMgaGF2ZSBlbGFwc2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24obmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbihhbnN3ZXIpKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgIHRoaXMucGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKS50aGVuKCgpID0+IHJlc29sdmUoKSkuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZW1vdGUgSUNFIGNhbmRpZGF0ZSByZWNlaXZlZCcsIGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdQZWVyQ29ubmVjdGlvbiBvYmplY3QgaXMgY2xvc2VkJykpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdzdGFibGUnOlxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnBjLnJlbW90ZURlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKS5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn1cblxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclJlY3Zvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRvbmx5IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRvbmx5JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlclNlbmRyZWN2IGV4dGVuZHMgV2ViUnRjUGVlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgY29uZmlndXJhdGlvbi5tb2RlID0gJ3NlbmRyZWN2JztcbiAgICAgICAgc3VwZXIoY29uZmlndXJhdGlvbik7XG4gICAgfVxufSIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAxOSBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pby8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIHN0YXRzOiBhbnkgPSB7XG4gICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IDAsXG4gICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAwLFxuICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAwLFxuICAgICAgICAgICAgICAgIGZyYW1lc0RlY29kZWQ6IDAsXG4gICAgICAgICAgICAgICAgbmFja0NvdW50OiAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG91dGJvdW5kOiB7XG4gICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogMCxcbiAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogMCxcbiAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiAwLFxuICAgICAgICAgICAgICAgIG5hY2tDb3VudDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RyZWFtOiBTdHJlYW0pIHsgfVxuXG4gICAgcHVibGljIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG5cbiAgICAgICAgY29uc3QgZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZWxhc3Rlc3QtaW5zdHJ1bWVudGF0aW9uJyk7XG5cbiAgICAgICAgaWYgKCEhZWxhc3Rlc3RJbnN0cnVtZW50YXRpb24pIHtcbiAgICAgICAgICAgIC8vIEVsYXNUZXN0IGluc3RydW1lbnRhdGlvbiBvYmplY3QgZm91bmQgaW4gbG9jYWwgc3RvcmFnZVxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dlYlJ0YyBzdGF0cyBlbmFibGVkIGZvciBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNFbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gSlNPTi5wYXJzZShlbGFzdGVzdEluc3RydW1lbnRhdGlvbik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSW50ZXJ2YWwgPSBpbnN0cnVtZW50YXRpb24ud2VicnRjLmludGVydmFsOyAgLy8gSW50ZXJ2YWwgaW4gc2Vjb25kc1xuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkoaW5zdHJ1bWVudGF0aW9uKSk7XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoaW5zdHJ1bWVudGF0aW9uKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRTdGF0c0Fnbm9zdGljKHRoaXMuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9jYWxDYW5kaWRhdGVJZCwgcmVtb3RlQ2FuZGlkYXRlSWQsIGdvb2dDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdGVDYW5kaWRhdGVzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzdGF0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICdsb2NhbGNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzW3N0YXQuaWRdID0gc3RhdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXQudHlwZSA9PT0gJ3JlbW90ZWNhbmRpZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlc1tzdGF0LmlkXSA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0LnR5cGUgPT09ICdnb29nQ2FuZGlkYXRlUGFpcicgJiYgKHN0YXQuZ29vZ0FjdGl2ZUNvbm5lY3Rpb24gPT09ICd0cnVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIgPSBzdGF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZUlkID0gc3RhdC5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGVJZCA9IHN0YXQucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXNbbG9jYWxDYW5kaWRhdGVJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXBBZGRyZXNzKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydE51bWJlcikgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9ICEhY2FuZFswXSA/IGNhbmRbMF0uY2FuZGlkYXRlIDogJ0VSUk9SOiBDYW5ub3QgZmluZCBsb2NhbCBjYW5kaWRhdGUgaW4gbGlzdCBvZiBzZW50IElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXNbcmVtb3RlQ2FuZGlkYXRlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZmluYWxSZW1vdGVDYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kTGlzdCA9IHRoaXMuc3RyZWFtLmdldFJlbW90ZUljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmlwQWRkcmVzcykgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0TnVtYmVyKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnByaW9yaXR5KSA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSAhIWNhbmRbMF0gPyBjYW5kWzBdLmNhbmRpZGF0ZSA6ICdFUlJPUjogQ2Fubm90IGZpbmQgcmVtb3RlIGNhbmRpZGF0ZSBpbiBsaXN0IG9mIHJlY2VpdmVkIElDRSBjYW5kaWRhdGVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ0NhbmRpZGF0ZVBhaXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGU6IGZpbmFsTG9jYWxDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlOiBmaW5hbFJlbW90ZUNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoJ1NlbGVjdGVkIElDRSBjYW5kaWRhdGUgaW5mbyBvbmx5IGF2YWlsYWJsZSBmb3IgQ2hyb21lJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KGluc3RydW1lbnRhdGlvbik6IHZvaWQge1xuXG4gICAgICAgIGNvbnN0IHNlbmRQb3N0ID0gKGpzb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0dHA6IFhNTEh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBjb25zdCB1cmw6IHN0cmluZyA9IGluc3RydW1lbnRhdGlvbi53ZWJydGMuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTtcblxuICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgICAgICAgICBodHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHsgLy8gQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdGhlIHN0YXRlIGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgaWYgKGh0dHAucmVhZHlTdGF0ZSA9PT0gNCAmJiBodHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJSdGMgc3RhdHMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gJyArIHVybCArICcgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHR0cC5zZW5kKGpzb24pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGYgPSAoc3RhdHMpID0+IHtcblxuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKChzdGF0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHN0YXQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdm9pZCBmaXJlZm94IGVtcHR5IG91dGJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5uYWNrQ291bnQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlzUmVtb3RlID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXQuaWQuc3RhcnRzV2l0aCgnaW5ib3VuZCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5yZW1vdGVJZC5zdGFydHNXaXRoKCdpbmJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX2luYm91bmRfJyArIHN0YXQubWVkaWFUeXBlICsgJ18nICsgc3RhdC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgaml0ID0gc3RhdC5qaXR0ZXIgKiAxMDAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlcjogaml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogKHN0YXQucGFja2V0c1JlY2VpdmVkIC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiAoc3RhdC5wYWNrZXRzTG9zdCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogJ2J5dGVzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiAncGFja2V0cycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6ICdwYWNrZXRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0Lm1lZGlhVHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3NbJ2ZyYW1lc0RlY29kZWQnXSA9IChzdGF0LmZyYW1lc0RlY29kZWQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8uZnJhbWVzRGVjb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5uYWNrQ291bnQgLSB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRGVjb2RlZCddID0gJ2ZyYW1lcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLmZyYW1lc0RlY29kZWQgPSBzdGF0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCA9IHN0YXQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQgPSBzdGF0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCA9IHN0YXQucGFja2V0c0xvc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlYyc6IGluc3RydW1lbnRhdGlvbi5leGVjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb21wb25lbnQnOiBpbnN0cnVtZW50YXRpb24uY29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXRfdHlwZSc6IG1ldHJpY0lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1fdHlwZSc6ICdjb21wb3NlZF9tZXRyaWNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25bbWV0cmljSWRdID0gbWV0cmljcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHN0YXQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZmlyZWZveCBlbXB0eSBpbmJvdW5kLXJ0cCBzdGF0aXN0aWNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdC5pc1JlbW90ZSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0LmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ291dGJvdW5kJylcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQ6IChzdGF0LmJ5dGVzU2VudCAtIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNTZW50OiAncGFja2V0cydcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzWydmcmFtZXNFbmNvZGVkJ10gPSAoc3RhdC5mcmFtZXNFbmNvZGVkIC0gdGhpcy5zdGF0cy5vdXRib3VuZC52aWRlby5mcmFtZXNFbmNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0c1snZnJhbWVzRW5jb2RlZCddID0gJ2ZyYW1lcyc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMub3V0Ym91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzU2VudCA9IHN0YXQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoc3RhdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tcG9uZW50JzogaW5zdHJ1bWVudGF0aW9uLmNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtJzogJ3dlYlJ0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtX3R5cGUnOiAnY29tcG9zZWRfbWV0cmljcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3VuaXRzJzogdW5pdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uW21ldHJpY0lkXSA9IG1ldHJpY3M7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQb3N0KEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXQgPSBzdGF0c1trZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAnc3NyYycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdieXRlc1JlY2VpdmVkJyBpbiBzdGF0ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdC5tZWRpYVR5cGUgPT09ICdhdWRpbycgJiYgJ2F1ZGlvT3V0cHV0TGV2ZWwnIGluIHN0YXQpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXQubWVkaWFUeXBlID09PSAndmlkZW8nICYmICdxcFN1bScgaW4gc3RhdClcbiAgICAgICAgICAgICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmJvdW5kLXJ0cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY0lkID0gJ3dlYnJ0Y19pbmJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IChzdGF0LmJ5dGVzUmVjZWl2ZWQgLSB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLmJ5dGVzUmVjZWl2ZWQpIC8gdGhpcy5zdGF0c0ludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6IHN0YXQuZ29vZ0ppdHRlckJ1ZmZlck1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IChzdGF0LnBhY2tldHNSZWNlaXZlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1JlY2VpdmVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IChzdGF0LnBhY2tldHNMb3N0IC0gdGhpcy5zdGF0cy5pbmJvdW5kW3N0YXQubWVkaWFUeXBlXS5wYWNrZXRzTG9zdCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaXR0ZXI6ICdtcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogJ3BhY2tldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRGVjb2RlZCddID0gKHN0YXQuZnJhbWVzRGVjb2RlZCAtIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkKSAvIHRoaXMuc3RhdHNJbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snbmFja0NvdW50J10gPSAoc3RhdC5nb29nTmFja3NTZW50IC0gdGhpcy5zdGF0cy5pbmJvdW5kLnZpZGVvLm5hY2tDb3VudCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNEZWNvZGVkJ10gPSAnZnJhbWVzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHNbJ25hY2tDb3VudCddID0gJ3BhY2tldHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZC52aWRlby5mcmFtZXNEZWNvZGVkID0gc3RhdC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmQudmlkZW8ubmFja0NvdW50ID0gc3RhdC5nb29nTmFja3NTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNSZWNlaXZlZCA9IHN0YXQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLmluYm91bmRbc3RhdC5tZWRpYVR5cGVdLnBhY2tldHNSZWNlaXZlZCA9IHN0YXQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMuaW5ib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c0xvc3QgPSBzdGF0LnBhY2tldHNMb3N0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnYnl0ZXNTZW50JyBpbiBzdGF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0Ym91bmQtcnRwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0cmljSWQgPSAnd2VicnRjX291dGJvdW5kXycgKyBzdGF0Lm1lZGlhVHlwZSArICdfJyArIHN0YXQuc3NyYztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldHJpY3MgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogKHN0YXQuYnl0ZXNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50KSAvIHRoaXMuc3RhdHNJbnRlcnZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IChzdGF0LnBhY2tldHNTZW50IC0gdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQpIC8gdGhpcy5zdGF0c0ludGVydmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiAnYnl0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogJ3BhY2tldHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdC5tZWRpYVR5cGUgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljc1snZnJhbWVzRW5jb2RlZCddID0gKHN0YXQuZnJhbWVzRW5jb2RlZCAtIHRoaXMuc3RhdHMub3V0Ym91bmQudmlkZW8uZnJhbWVzRW5jb2RlZCkgLyB0aGlzLnN0YXRzSW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzWydmcmFtZXNFbmNvZGVkJ10gPSAnZnJhbWVzJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRzLm91dGJvdW5kLnZpZGVvLmZyYW1lc0VuY29kZWQgPSBzdGF0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0uYnl0ZXNTZW50ID0gc3RhdC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0cy5vdXRib3VuZFtzdGF0Lm1lZGlhVHlwZV0ucGFja2V0c1NlbnQgPSBzdGF0LnBhY2tldHNTZW50O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZShzdGF0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWMnOiBpbnN0cnVtZW50YXRpb24uZXhlYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbXBvbmVudCc6IGluc3RydW1lbnRhdGlvbi5jb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW0nOiAnd2ViUnRjJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V0X3R5cGUnOiBtZXRyaWNJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbV90eXBlJzogJ2NvbXBvc2VkX21ldHJpY3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndW5pdHMnOiB1bml0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvblttZXRyaWNJZF0gPSBtZXRyaWNzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBvc3QoSlNPTi5zdHJpbmdpZnkoanNvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZ2V0U3RhdHNBZ25vc3RpYyh0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLCBmLCAoZXJyb3IpID0+IHsgY29uc29sZS5sb2coZXJyb3IpOyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YW5kYXJkaXplUmVwb3J0KHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRSZXBvcnQgPSB7fTtcblxuICAgICAgICBpZiAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignRmlyZWZveCcpICE9PSAtMSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzcG9uc2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZVtrZXldKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2UucmVzdWx0KCkuZm9yRWFjaChyZXBvcnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRTdGF0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICB0eXBlOiByZXBvcnQudHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U3RhdHNBZ25vc3RpYyhwYywgc3VjY2Vzc0NiLCBmYWlsdXJlQ2IpIHtcbiAgICAgICAgaWYgKHBsYXRmb3JtLm5hbWUhLmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGdldFN0YXRzIHRha2VzIGFyZ3MgaW4gZGlmZmVyZW50IG9yZGVyIGluIENocm9tZSBhbmQgRmlyZWZveFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKG51bGwpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZmFpbHVyZUNiKTtcbiAgICAgICAgfSBlbHNlIGlmICgocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignQ2hyb21lJykgIT09IC0xKSB8fCAocGxhdGZvcm0ubmFtZSEuaW5kZXhPZignT3BlcmEnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJbiBDaHJvbWUsIHRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGFyZSByZXZlcnNlZFxuICAgICAgICAgICAgcmV0dXJuIHBjLmdldFN0YXRzKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuc3RhbmRhcmRpemVSZXBvcnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYihyZXBvcnQpO1xuICAgICAgICAgICAgfSwgbnVsbCwgZmFpbHVyZUNiKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ== diff --git a/openvidu-mvc-node/views/session.ejs b/openvidu-mvc-node/views/session.ejs index 8984a1a7e..d15cc21be 100644 --- a/openvidu-mvc-node/views/session.ejs +++ b/openvidu-mvc-node/views/session.ejs @@ -14,7 +14,7 @@ - + diff --git a/openvidu-react-native/package-lock.json b/openvidu-react-native/package-lock.json index 495fd0e24..48901e440 100644 --- a/openvidu-react-native/package-lock.json +++ b/openvidu-react-native/package-lock.json @@ -1,13 +1,13 @@ { "name": "openvidu_react_native", - "version": "2.10.0", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } @@ -16,6 +16,7 @@ "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", @@ -37,6 +38,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -44,18 +46,19 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", "requires": { - "@babel/types": "^7.4.4", + "@babel/types": "^7.5.5", "jsesc": "^2.5.1", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "source-map": "^0.5.0", "trim-right": "^1.0.1" } @@ -97,26 +100,26 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", - "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz", + "integrity": "sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4" } }, "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { @@ -155,11 +158,11 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.5.5" } }, "@babel/helper-module-imports": { @@ -171,16 +174,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { @@ -197,11 +200,11 @@ "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/helper-remap-async-to-generator": { @@ -217,14 +220,14 @@ } }, "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" } }, "@babel/helper-simple-access": { @@ -256,19 +259,19 @@ } }, "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", "requires": { "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -276,9 +279,9 @@ } }, "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==" }, "@babel/plugin-external-helpers": { "version": "7.2.0", @@ -289,18 +292,18 @@ } }, "@babel/plugin-proposal-class-properties": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz", - "integrity": "sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", + "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.4", + "@babel/helper-create-class-features-plugin": "^7.5.5", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-proposal-export-default-from": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.2.0.tgz", - "integrity": "sha512-NVfNe7F6nsasG1FnvcFxh2FN0l04ZNe75qTOAVOILWPam0tw9a63RtT/Dab8dPjedZa4fTQaQ83yMMywF9OSug==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz", + "integrity": "sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-export-default-from": "^7.2.0" @@ -316,9 +319,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", - "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", + "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" @@ -431,9 +434,9 @@ } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -449,25 +452,25 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", + "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", + "@babel/helper-define-map": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4", "globals": "^11.1.0" } @@ -481,9 +484,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -540,13 +543,14 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", "requires": { "@babel/helper-module-transforms": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-object-assign": { @@ -558,12 +562,12 @@ } }, "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" + "@babel/helper-replace-supers": "^7.5.5" } }, "@babel/plugin-transform-parameters": { @@ -603,9 +607,9 @@ } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", - "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", + "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0" @@ -620,9 +624,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz", - "integrity": "sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", + "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -665,10 +669,11 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz", - "integrity": "sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz", + "integrity": "sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==", "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.5", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-typescript": "^7.2.0" } @@ -684,22 +689,22 @@ } }, "@babel/register": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.4.tgz", - "integrity": "sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.5.5.tgz", + "integrity": "sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==", "requires": { "core-js": "^3.0.0", "find-cache-dir": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "mkdirp": "^0.5.1", "pirates": "^4.0.0", "source-map-support": "^0.5.9" }, "dependencies": { "core-js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.3.tgz", - "integrity": "sha512-PWZ+ZfuaKf178BIAg+CRsljwjIMRV8MY00CbZczkR6Zk5LfkSkjGoaab3+bqRQWVITNZxQB7TFYz+CFcyuamvA==" + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", + "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" } } }, @@ -707,14 +712,16 @@ "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", + "dev": true, "requires": { "regenerator-runtime": "^0.13.2" }, "dependencies": { "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true } } }, @@ -729,19 +736,19 @@ } }, "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" }, "dependencies": { "debug": { @@ -760,12 +767,12 @@ } }, "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, @@ -2500,9 +2507,9 @@ } }, "@react-native-community/cli": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-1.9.9.tgz", - "integrity": "sha512-puO2sfbAEimXCtJQK0N2CHzQCKPd97HQKfOG7V6sq8pmcjHPg7Q1MT6fjJjrlzhR0tKOGltpb6N8hcWsg9pNgg==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-1.11.2.tgz", + "integrity": "sha512-5NuYd30f5PCTrGUbZLnusZKv5nfTWvTDTRa/3Q4vwdMnUQrhm9sZXWGQ5CnFoQ7cE58EAqhj6/ShXeJF3DZ9uQ==", "requires": { "chalk": "^1.1.1", "commander": "^2.19.0", @@ -2679,23 +2686,23 @@ }, "dependencies": { "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", "dev": true } } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -3136,11 +3143,11 @@ "dev": true }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "async-limiter": { @@ -3195,12 +3202,21 @@ "slash": "^2.0.0" } }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, "babel-plugin-istanbul": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz", - "integrity": "sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", "dev": true, "requires": { + "@babel/helper-plugin-utils": "^7.0.0", "find-up": "^3.0.0", "istanbul-lib-instrument": "^3.3.0", "test-exclude": "^5.2.3" @@ -3460,9 +3476,9 @@ } }, "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", "requires": { "node-int64": "^0.4.0" } @@ -3862,15 +3878,15 @@ } }, "cssom": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, "cssstyle": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", - "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { "cssom": "0.3.x" @@ -3937,7 +3953,6 @@ "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" } @@ -4385,6 +4400,27 @@ "through2": "^2.0.0" }, "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -4394,6 +4430,19 @@ "shebang-command": "^1.2.0", "which": "^1.2.9" } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -5024,8 +5073,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "gauge": { "version": "1.2.7", @@ -5111,9 +5159,9 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "growly": { "version": "1.3.0", @@ -5192,8 +5240,7 @@ "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 + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-unicode": { "version": "2.0.1", @@ -5274,12 +5321,12 @@ } }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", "requires": { "depd": "~1.1.2", - "inherits": "2.0.3", + "inherits": "2.0.4", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" @@ -5343,9 +5390,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "inquirer": { "version": "3.3.0", @@ -5650,9 +5697,9 @@ }, "dependencies": { "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -8234,9 +8281,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.pad": { "version": "4.5.1", @@ -8411,12 +8458,50 @@ "yargs": "^9.0.0" }, "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "metro-react-native-babel-preset": { @@ -8473,6 +8558,11 @@ "requires": { "mime-db": "~1.23.0" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -8493,6 +8583,42 @@ "@babel/register": "^7.0.0", "core-js": "^2.2.2", "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "metro-babel-transformer": { @@ -8501,6 +8627,42 @@ "integrity": "sha512-+tOnZZzOzufB86ASdfimUEGB1jBKsdsVpPdjNJZkueTFyvYlGqWDQKHM1w9bwKMeM/czPQ48Y6m8Bou6le0X4w==", "requires": { "@babel/core": "^7.0.0" + }, + "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "metro-babel7-plugin-react-transform": { @@ -8631,6 +8793,35 @@ "metro-react-native-babel-preset": "0.51.0" }, "dependencies": { + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, "metro-babel-transformer": { "version": "0.51.0", "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.51.0.tgz", @@ -8688,6 +8879,11 @@ "metro-babel7-plugin-react-transform": "0.51.0", "react-transform-hmr": "^1.0.4" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -8772,9 +8968,9 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -9014,8 +9210,7 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -9032,6 +9227,17 @@ } } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, "object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", @@ -9096,108 +9302,52 @@ } }, "openvidu-browser": { - "version": "file:openvidu-browser-2.9.0.tgz", - "integrity": "sha512-DBfX4VO2pUKvtnP5JSH5hHuH5oetRnKEIlBE/8/GPEZ3lI6yuMOP59o6SfYomDW2UPMvxWSaTF4dHMBDM6a8FA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/openvidu-browser/-/openvidu-browser-2.11.0.tgz", + "integrity": "sha512-dXnzHA9gf0Fhl88YijmPbFT/d7ERUHOMrqGObVeDc5NvG/7y2HCFafb/42O/mZ86IkBZnmqSrl6Q63aNlUZ2iA==", "requires": { - "@types/node": "11.13.6", + "@types/node": "12.6.8", "@types/platform": "1.3.2", - "base-64": "^0.1.0", "freeice": "2.2.2", "hark": "1.2.3", "platform": "1.3.5", - "react-native-webrtc": "1.69.1", "uuid": "3.3.2", "wolfy87-eventemitter": "5.2.6" }, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" - }, - "@types/fs-extra": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.5.tgz", - "integrity": "sha512-w7iqhDH9mN8eLClQOYTkhdYUOSpp25eXxfc6VbFOGtzxW34JcvctH2bKjj4jD4++z4R5iO5D+pg48W2e03I65A==", - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", - "requires": { - "handlebars": "*" - } - }, - "@types/highlight.js": { - "version": "9.12.3", - "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", - "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==" - }, - "@types/lodash": { - "version": "4.14.123", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz", - "integrity": "sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==" - }, - "@types/marked": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz", - "integrity": "sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==" - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "11.13.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.6.tgz", - "integrity": "sha512-Xoo/EBzEe8HxTSwaZNLZjaW6M6tA/+GmD3/DZ6uo8qSaolE/9Oarko0oV1fVfrLqOz0tx0nXJB4rdD5c+vixLw==" + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==" }, "@types/platform": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.2.tgz", "integrity": "sha512-Tn6OuJDAG7bJbyi4R7HqcxXp1w2lmIxVXqyNhPt1Bm0FO2EWIi3CI87JVzF7ncqK0ZMPuUycS3wTMIk85EeF1Q==" }, - "@types/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==", - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -9213,9 +9363,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-dynamic-import": { "version": "4.0.0", @@ -9223,20 +9373,20 @@ "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==" }, "acorn-node": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", - "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.7.0.tgz", + "integrity": "sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw==", "requires": { - "acorn": "^6.0.2", + "acorn": "^6.1.1", "acorn-dynamic-import": "^4.0.0", - "acorn-walk": "^6.1.0", + "acorn-walk": "^6.1.1", "xtend": "^4.0.1" } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, "amdefine": { "version": "1.0.1", @@ -9356,10 +9506,11 @@ } }, "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "requires": { + "object-assign": "^4.1.1", "util": "0.10.3" }, "dependencies": { @@ -9409,6 +9560,14 @@ "postcss": "~4.1.12" } }, + "backbone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", + "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", + "requires": { + "underscore": ">=1.8.3" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -9464,11 +9623,6 @@ } } }, - "base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" - }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", @@ -9565,9 +9719,9 @@ } }, "browserify": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", - "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", + "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -9762,9 +9916,9 @@ } }, "caniuse-db": { - "version": "1.0.30000962", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000962.tgz", - "integrity": "sha512-zkAkM+FSotCJZxdBDHoMhUWGUJzJjyWTTt4h33w3VFM1pirqxRHGgGIjireWkdYZQVRSYScNANixGtGycIFhmg==" + "version": "1.0.30000986", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000986.tgz", + "integrity": "sha512-8SKJ12AFwG0ReMjPwRH+keFsX/ucw2bi6LC7upeXBvxjgrMqHaTxgYhkRGm+eOwUWvVcqXDgqM7QNlRJMhvXZg==" }, "chalk": { "version": "2.4.2", @@ -9777,9 +9931,9 @@ } }, "chokidar": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", - "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -10009,9 +10163,9 @@ }, "dependencies": { "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" } } }, @@ -10192,9 +10346,9 @@ } }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -10242,11 +10396,6 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, - "event-target-shim": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz", - "integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=" - }, "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", @@ -10515,11 +10664,11 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -10530,9 +10679,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.8.tgz", - "integrity": "sha512-tPvHgPGB7m40CZ68xqFGkKuzN+RnpGmSV+hgeKxhRpbxdqKXUFJGC3yonBOLzQBcJyGpdZFDfCsdOC2KFsXzeA==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "optional": true, "requires": { "nan": "^2.12.1", @@ -11044,9 +11193,9 @@ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=" }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11098,9 +11247,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, "grunt": { "version": "1.0.4", @@ -11354,11 +11503,11 @@ }, "dependencies": { "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } } } @@ -11422,11 +11571,11 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "chalk": { @@ -11598,9 +11747,9 @@ } }, "highlight.js": { - "version": "9.15.6", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.6.tgz", - "integrity": "sha512-zozTAWM1D6sozHo8kqhfYgsac+B+q0PmsjXeyDrYIHHcBN0zTVT66+s2GW1GZv7DbyaROdLXKdabwS/WqPyIdQ==" + "version": "9.15.8", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.8.tgz", + "integrity": "sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA==" }, "hmac-drbg": { "version": "1.0.1", @@ -11636,9 +11785,9 @@ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=" }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "https-browserify": { "version": "1.0.0", @@ -11676,9 +11825,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -11888,6 +12037,11 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-base64": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", @@ -11944,20 +12098,12 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" }, "labeled-stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", - "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", + "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", "requires": { "inherits": "^2.0.1", - "isarray": "^2.0.4", "stream-splicer": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", - "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==" - } } }, "liftoff": { @@ -12006,23 +12152,15 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=" }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -12037,6 +12175,11 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" }, + "lunr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.6.tgz", + "integrity": "sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -12064,9 +12207,9 @@ } }, "marked": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", - "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" }, "maxmin": { "version": "2.1.0", @@ -12204,9 +12347,9 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -12238,13 +12381,13 @@ } }, "module-deps": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", - "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.1.tgz", + "integrity": "sha512-UnEn6Ah36Tu4jFiBbJVUtt0h+iXqxpLqDvPS8nllbw5RZFmNJ1+Mz5BjYnM9ieH80zyxHkARGLnMIHlPK5bu6A==", "requires": { "JSONStream": "^1.0.3", "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.0", + "cached-path-relative": "^1.0.2", "concat-stream": "~1.6.0", "defined": "^1.0.0", "detective": "^5.0.2", @@ -12265,9 +12408,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "optional": true }, "nanomatch": { @@ -12294,9 +12437,9 @@ "integrity": "sha1-dDmFMW49tFkoG1hxaehFc1oFQ58=" }, "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" }, "nopt": { "version": "3.0.6", @@ -12638,25 +12781,15 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -12723,21 +12856,6 @@ } } }, - "react-is": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" - }, - "react-native-webrtc": { - "version": "1.69.1", - "resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-1.69.1.tgz", - "integrity": "sha512-tUcu3zRvOCSgS2aj3hlSKVdmRiR6NbQdhPSWJQR2dBct8MgfoW/fKrGLWcAWbt8wmXMJYErQq0V/P3+gOOd+7w==", - "requires": { - "base64-js": "^1.1.2", - "event-target-shim": "^1.0.5", - "prop-types": "^15.5.10" - } - }, "read-only-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", @@ -12779,6 +12897,11 @@ "util-deprecate": "~1.0.1" }, "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12849,9 +12972,9 @@ } }, "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } @@ -12893,9 +13016,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-json-parse": { "version": "1.0.1", @@ -12926,9 +13049,9 @@ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -13138,9 +13261,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -13205,9 +13328,9 @@ } }, "stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", - "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", + "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.2" @@ -13224,6 +13347,13 @@ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -13323,9 +13453,9 @@ } }, "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==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -13402,14 +13532,14 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", + "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -13417,7 +13547,7 @@ "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -13452,50 +13582,43 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.14.2.tgz", - "integrity": "sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ==", - "requires": { - "@types/fs-extra": "^5.0.3", - "@types/handlebars": "^4.0.38", - "@types/highlight.js": "^9.12.3", - "@types/lodash": "^4.14.110", - "@types/marked": "^0.4.0", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.15.0.tgz", + "integrity": "sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw==", + "requires": { "@types/minimatch": "3.0.3", - "@types/shelljs": "^0.8.0", - "fs-extra": "^7.0.0", - "handlebars": "^4.0.6", - "highlight.js": "^9.13.1", - "lodash": "^4.17.10", - "marked": "^0.4.0", + "fs-extra": "^8.1.0", + "handlebars": "^4.1.2", + "highlight.js": "^9.15.8", + "lodash": "^4.17.15", + "marked": "^0.7.0", "minimatch": "^3.0.0", - "progress": "^2.0.0", - "shelljs": "^0.8.2", - "typedoc-default-themes": "^0.5.0", - "typescript": "3.2.x" - }, - "dependencies": { - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==" - } + "progress": "^2.0.3", + "shelljs": "^0.8.3", + "typedoc-default-themes": "^0.6.0", + "typescript": "3.5.x" } }, "typedoc-default-themes": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz", - "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.6.0.tgz", + "integrity": "sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw==", + "requires": { + "backbone": "^1.4.0", + "jquery": "^3.4.1", + "lunr": "^2.3.6", + "underscore": "^1.9.1" + } }, "typescript": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.4.tgz", - "integrity": "sha512-xt5RsIRCEaf6+j9AyOBgvVuAec0i92rgCaS3S+UVf5Z/vF2Hvtsw08wtUTJqp4djwznoAgjSxeCcU4r+CcDBJA==" + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==" }, "uglify-js": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.6.tgz", - "integrity": "sha512-YDKRX8F0Y+Jr7LhoVk0n4G7ltR3Y7qFAj+DtVBthlOgCcIj1hyMigCfousVfn9HKmvJ+qiFlLDwaHx44/e5ZKw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" @@ -13530,6 +13653,11 @@ "xtend": "^4.0.1" } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -13540,35 +13668,14 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "universalify": { @@ -13654,6 +13761,13 @@ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "util-deprecate": { @@ -13667,9 +13781,9 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8flags": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz", - "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", "requires": { "homedir-polyfill": "^1.0.1" } @@ -13689,11 +13803,12 @@ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -13711,9 +13826,9 @@ } }, "wildemitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.0.tgz", - "integrity": "sha1-Kd06ctaZw+J53QIcPNIVC4LJohE=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.1.tgz", + "integrity": "sha512-UMmSUoIQSir+XbBpTxOTS53uJ8s/lVhADCkEbhfRjUGFDPme/XGOb0sBWLx5sTz7Wx/2+TlAw1eK9O5lw5PiEw==" }, "wolfy87-eventemitter": { "version": "5.2.6", @@ -13745,9 +13860,9 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } }, @@ -14142,9 +14257,9 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "promise": { "version": "7.3.1", @@ -14180,9 +14295,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", "dev": true }, "pump": { @@ -14255,9 +14370,9 @@ "integrity": "sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==" }, "react-devtools-core": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-3.6.1.tgz", - "integrity": "sha512-I/LSX+tpeTrGKaF1wXSfJ/kP+6iaP2JfshEjW8LtQBdz6c6HhzOJtjZXhqOUrAdysuey8M1/JgPY1flSVVt8Ig==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-3.6.3.tgz", + "integrity": "sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ==", "requires": { "shell-quote": "^1.6.1", "ws": "^3.3.1" @@ -14342,6 +14457,21 @@ "yargs": "^9.0.0" }, "dependencies": { + "@babel/runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -14443,9 +14573,9 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", - "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", "requires": { "private": "^0.1.6" } @@ -14592,9 +14722,9 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } @@ -15047,9 +15177,9 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -15122,9 +15252,9 @@ } }, "sisteransi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz", + "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==", "dev": true }, "slash": { @@ -15304,9 +15434,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -15801,35 +15931,14 @@ "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "universalify": { @@ -16125,9 +16234,9 @@ "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "3.2.1", diff --git a/openvidu-react-native/package.json b/openvidu-react-native/package.json index df85c9810..ea054007e 100644 --- a/openvidu-react-native/package.json +++ b/openvidu-react-native/package.json @@ -1,6 +1,6 @@ { "name": "openvidu_react_native", - "version": "2.10.0", + "version": "2.11.0", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", @@ -8,7 +8,7 @@ }, "dependencies": { "axios": "0.19.0", - "openvidu-browser": "2.10.0", + "openvidu-browser": "2.11.0", "react": "16.8.6", "react-native": "0.59.9" }, diff --git a/openvidu-recording-java/pom.xml b/openvidu-recording-java/pom.xml index 6e3a1922f..544a54e59 100644 --- a/openvidu-recording-java/pom.xml +++ b/openvidu-recording-java/pom.xml @@ -5,7 +5,7 @@ io.openvidu openvidu-recording-java - 2.10.0 + 2.11.0 jar openvidu-recording-java @@ -51,7 +51,7 @@ io.openvidu openvidu-java-client - 2.10.0 + 2.11.0 org.junit.jupiter diff --git a/openvidu-recording-java/src/main/resources/static/index.html b/openvidu-recording-java/src/main/resources/static/index.html index 871e4d6ed..8d625c70c 100644 --- a/openvidu-recording-java/src/main/resources/static/index.html +++ b/openvidu-recording-java/src/main/resources/static/index.html @@ -17,7 +17,7 @@ - + + - - + + diff --git a/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.css b/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.css deleted file mode 100644 index 5a3df4226..000000000 --- a/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.css +++ /dev/null @@ -1 +0,0 @@ -html{height:100%}body{margin:0;font-family:Ubuntu,sans-serif;height:100%;width:100%}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/materialicons/v38/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2')}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}.mat-badge-content{font-weight:600;font-size:12px;font-family:Roboto,"Helvetica Neue",sans-serif}.mat-badge-small .mat-badge-content{font-size:6px}.mat-badge-large .mat-badge-content{font-size:24px}.mat-h1,.mat-headline,.mat-typography h1{font:400 24px/32px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h2,.mat-title,.mat-typography h2{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h3,.mat-subheading-2,.mat-typography h3{font:400 16px/28px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h4,.mat-subheading-1,.mat-typography h4{font:400 15px/24px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h5,.mat-typography h5{font:400 11.62px/20px Roboto,"Helvetica Neue",sans-serif;margin:0 0 12px}.mat-h6,.mat-typography h6{font:400 9.38px/20px Roboto,"Helvetica Neue",sans-serif;margin:0 0 12px}.mat-body-2,.mat-body-strong{font:500 14px/24px Roboto,"Helvetica Neue",sans-serif}.mat-body,.mat-body-1,.mat-typography{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-body p,.mat-body-1 p,.mat-typography p{margin:0 0 12px}.mat-caption,.mat-small{font:400 12px/20px Roboto,"Helvetica Neue",sans-serif}.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px Roboto,"Helvetica Neue",sans-serif;margin:0 0 56px;letter-spacing:-.05em}.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px;letter-spacing:-.02em}.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px;letter-spacing:-.005em}.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px}.mat-bottom-sheet-container{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-button,.mat-fab,.mat-flat-button,.mat-icon-button,.mat-mini-fab,.mat-raised-button,.mat-stroked-button{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500}.mat-button-toggle,.mat-card{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-card-title{font-size:24px;font-weight:500}.mat-card-header .mat-card-title{font-size:20px}.mat-card-content,.mat-card-subtitle{font-size:14px}.mat-checkbox{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-checkbox-layout .mat-checkbox-label{line-height:24px}.mat-chip{font-size:14px;font-weight:500}.mat-chip .mat-chip-remove.mat-icon,.mat-chip .mat-chip-trailing-icon.mat-icon{font-size:18px}.mat-table{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-header-cell{font-size:12px;font-weight:500}.mat-cell,.mat-footer-cell{font-size:14px}.mat-calendar{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-calendar-body{font-size:13px}.mat-calendar-body-label,.mat-calendar-period-button{font-size:14px;font-weight:500}.mat-calendar-table-header th{font-size:11px;font-weight:400}.mat-dialog-title{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif}.mat-expansion-panel-header{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:15px;font-weight:400}.mat-expansion-panel-content{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-form-field{font-size:inherit;font-weight:400;line-height:1.125;font-family:Roboto,"Helvetica Neue",sans-serif}.mat-form-field-wrapper{padding-bottom:1.34375em}.mat-form-field-prefix .mat-icon,.mat-form-field-suffix .mat-icon{font-size:150%;line-height:1.125}.mat-form-field-prefix .mat-icon-button,.mat-form-field-suffix .mat-icon-button{height:1.5em;width:1.5em}.mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-suffix .mat-icon-button .mat-icon{height:1.125em;line-height:1.125}.mat-form-field-infix{padding:.5em 0;border-top:.84375em solid transparent}.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-1.34375em) scale(.75);transform:translateY(-1.34375em) scale(.75);width:133.3333333333%}.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.34374em) scale(.75);transform:translateY(-1.34374em) scale(.75);width:133.3333433333%}.mat-form-field-label-wrapper{top:-.84375em;padding-top:.84375em}.mat-form-field-label{top:1.34375em}.mat-form-field-underline{bottom:1.34375em}.mat-form-field-subscript-wrapper{font-size:75%;margin-top:.6666666667em;top:calc(100% - 1.7916666667em)}.mat-form-field-appearance-legacy .mat-form-field-wrapper{padding-bottom:1.25em}.mat-form-field-appearance-legacy .mat-form-field-infix{padding:.4375em 0}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.3333333333%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00101px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00101px);-ms-transform:translateY(-1.28124em) scale(.75);width:133.3333433333%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00102px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00102px);-ms-transform:translateY(-1.28123em) scale(.75);width:133.3333533333%}.mat-form-field-appearance-legacy .mat-form-field-label{top:1.28125em}.mat-form-field-appearance-legacy .mat-form-field-subscript-wrapper{margin-top:.5416666667em;top:calc(100% - 1.6666666667em)}@media print{.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-1.28122em) scale(.75);transform:translateY(-1.28122em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.28121em) scale(.75);transform:translateY(-1.28121em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.2812em) scale(.75);transform:translateY(-1.2812em) scale(.75)}}.mat-form-field-appearance-fill .mat-form-field-infix{padding:.25em 0 .75em}.mat-form-field-appearance-fill .mat-form-field-label{top:1.09375em;margin-top:-.5em}.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-appearance-fill.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-.59375em) scale(.75);transform:translateY(-.59375em) scale(.75);width:133.3333333333%}.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-.59374em) scale(.75);transform:translateY(-.59374em) scale(.75);width:133.3333433333%}.mat-form-field-appearance-outline .mat-form-field-infix{padding:1em 0}.mat-form-field-appearance-outline .mat-form-field-label{top:1.84375em;margin-top:-.25em}.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-1.59375em) scale(.75);transform:translateY(-1.59375em) scale(.75);width:133.3333333333%}.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.59374em) scale(.75);transform:translateY(-1.59374em) scale(.75);width:133.3333433333%}.mat-grid-tile-footer,.mat-grid-tile-header{font-size:14px}.mat-grid-tile-footer .mat-line,.mat-grid-tile-header .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-grid-tile-footer .mat-line:nth-child(n+2),.mat-grid-tile-header .mat-line:nth-child(n+2){font-size:12px}input.mat-input-element{margin-top:-.0625em}.mat-menu-item{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:400}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px}.mat-radio-button,.mat-select{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-select-trigger{height:1.125em}.mat-slide-toggle-content{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-slider-thumb-label-text{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px;font-weight:500}.mat-stepper-horizontal,.mat-stepper-vertical{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-step-label{font-size:14px;font-weight:400}.mat-step-sub-label-error{font-weight:400}.mat-step-label-error{font-size:14px}.mat-step-label-selected{font-size:14px;font-weight:500}.mat-tab-group{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-tab-label,.mat-tab-link{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500}.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif;margin:0}.mat-tooltip{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:10px;padding-top:6px;padding-bottom:6px}.mat-tooltip-handset{font-size:14px;padding-top:8px;padding-bottom:8px}.mat-list-item,.mat-list-option{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-list-base .mat-list-item{font-size:16px}.mat-list-base .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-item .mat-line:nth-child(n+2){font-size:14px}.mat-list-base .mat-list-option{font-size:16px}.mat-list-base .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-option .mat-line:nth-child(n+2){font-size:14px}.mat-list-base[dense] .mat-list-item{font-size:12px}.mat-list-base[dense] .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-item .mat-line:nth-child(n+2),.mat-list-base[dense] .mat-list-option{font-size:12px}.mat-list-base[dense] .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-option .mat-line:nth-child(n+2){font-size:12px}.mat-list-base[dense] .mat-subheader{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px;font-weight:500}.mat-option{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:16px;color:rgba(0,0,0,.87)}.mat-optgroup-label{font:500 14px/24px Roboto,"Helvetica Neue",sans-serif;color:rgba(0,0,0,.54)}.mat-simple-snackbar{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500}.mat-ripple{overflow:hidden;position:relative}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,-webkit-transform 0s cubic-bezier(0,0,.2,1);transition:opacity,transform 0s cubic-bezier(0,0,.2,1);transition:opacity,transform 0s cubic-bezier(0,0,.2,1),-webkit-transform 0s cubic-bezier(0,0,.2,1);-webkit-transform:scale(0);transform:scale(0)}@media (-ms-high-contrast:active){.mat-ripple-element{display:none}}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;outline:0;-webkit-appearance:none;-moz-appearance:none}.cdk-global-overlay-wrapper,.cdk-overlay-container{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}@media screen and (-ms-high-contrast:active){.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}@-webkit-keyframes cdk-text-field-autofill-start{/*!*/}@keyframes cdk-text-field-autofill-start{/*!*/}@-webkit-keyframes cdk-text-field-autofill-end{/*!*/}@keyframes cdk-text-field-autofill-end{/*!*/}.cdk-text-field-autofill-monitored:-webkit-autofill{-webkit-animation-name:cdk-text-field-autofill-start;animation-name:cdk-text-field-autofill-start}.cdk-text-field-autofill-monitored:not(:-webkit-autofill){-webkit-animation-name:cdk-text-field-autofill-end;animation-name:cdk-text-field-autofill-end}textarea.cdk-textarea-autosize{resize:none}textarea.cdk-textarea-autosize-measuring{height:auto!important;overflow:hidden!important;padding:2px 0!important;box-sizing:content-box!important}.mat-ripple-element{background-color:rgba(0,0,0,.1)}.mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled),.mat-option:focus:not(.mat-option-disabled),.mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#eceff1}.mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#ffc107}.mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.mat-pseudo-checkbox::after{color:#fafafa}.mat-pseudo-checkbox-disabled{color:#b0b0b0}.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate,.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-indeterminate{background:#ffc107}.mat-primary .mat-pseudo-checkbox-checked,.mat-primary .mat-pseudo-checkbox-indeterminate{background:#eceff1}.mat-warn .mat-pseudo-checkbox-checked,.mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.mat-elevation-z0{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-elevation-z1{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.mat-elevation-z2{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-elevation-z3{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.mat-elevation-z4{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-elevation-z5{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)}.mat-elevation-z6{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-elevation-z7{box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12)}.mat-elevation-z8{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.mat-elevation-z9{box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12)}.mat-elevation-z10{box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12)}.mat-elevation-z11{box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12)}.mat-elevation-z12{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-elevation-z13{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12)}.mat-elevation-z14{box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12)}.mat-elevation-z15{box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12)}.mat-elevation-z16{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.mat-elevation-z17{box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12)}.mat-elevation-z18{box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12)}.mat-elevation-z19{box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12)}.mat-elevation-z20{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12)}.mat-elevation-z21{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12)}.mat-elevation-z22{box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12)}.mat-elevation-z23{box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12)}.mat-elevation-z24{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}.mat-app-background{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.mat-autocomplete-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}@media (-ms-high-contrast:active){.mat-badge-content{outline:solid 1px;border-radius:0}.mat-checkbox-disabled{opacity:.5}}.mat-badge-accent .mat-badge-content{background:#ffc107;color:rgba(0,0,0,.87)}.mat-badge-warn .mat-badge-content{color:#fff;background:#f44336}.mat-badge{position:relative}.mat-badge-hidden .mat-badge-content{display:none}.mat-badge-disabled .mat-badge-content{background:#b9b9b9;color:rgba(0,0,0,.38)}.mat-badge-content{color:rgba(0,0,0,.87);background:#eceff1;position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;-webkit-transform:scale(.6);transform:scale(.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.mat-badge-content.mat-badge-active{-webkit-transform:none;transform:none}.mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir=rtl] .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir=rtl] .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir=rtl] .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir=rtl] .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir=rtl] .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir=rtl] .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir=rtl] .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir=rtl] .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir=rtl] .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir=rtl] .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir=rtl] .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir=rtl] .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.mat-bottom-sheet-container{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.mat-button,.mat-icon-button,.mat-stroked-button{color:inherit;background:0 0}.mat-button.mat-primary,.mat-icon-button.mat-primary,.mat-stroked-button.mat-primary{color:#eceff1}.mat-button.mat-accent,.mat-icon-button.mat-accent,.mat-stroked-button.mat-accent{color:#ffc107}.mat-button.mat-warn,.mat-icon-button.mat-warn,.mat-stroked-button.mat-warn{color:#f44336}.mat-button.mat-accent[disabled],.mat-button.mat-primary[disabled],.mat-button.mat-warn[disabled],.mat-button[disabled][disabled],.mat-icon-button.mat-accent[disabled],.mat-icon-button.mat-primary[disabled],.mat-icon-button.mat-warn[disabled],.mat-icon-button[disabled][disabled],.mat-stroked-button.mat-accent[disabled],.mat-stroked-button.mat-primary[disabled],.mat-stroked-button.mat-warn[disabled],.mat-stroked-button[disabled][disabled]{color:rgba(0,0,0,.26)}.mat-button.mat-primary .mat-button-focus-overlay,.mat-icon-button.mat-primary .mat-button-focus-overlay,.mat-stroked-button.mat-primary .mat-button-focus-overlay{background-color:#eceff1}.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay,.mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:#ffc107}.mat-button.mat-warn .mat-button-focus-overlay,.mat-icon-button.mat-warn .mat-button-focus-overlay,.mat-stroked-button.mat-warn .mat-button-focus-overlay{background-color:#f44336}.mat-button[disabled] .mat-button-focus-overlay,.mat-icon-button[disabled] .mat-button-focus-overlay,.mat-stroked-button[disabled] .mat-button-focus-overlay{background-color:transparent}.mat-button .mat-ripple-element,.mat-icon-button .mat-ripple-element,.mat-stroked-button .mat-ripple-element{opacity:.1;background-color:currentColor}.mat-button-focus-overlay{background:#000}.mat-stroked-button:not([disabled]){border-color:rgba(0,0,0,.12)}.mat-fab,.mat-flat-button,.mat-mini-fab,.mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.mat-fab.mat-accent,.mat-fab.mat-primary,.mat-flat-button.mat-accent,.mat-flat-button.mat-primary,.mat-mini-fab.mat-accent,.mat-mini-fab.mat-primary,.mat-raised-button.mat-accent,.mat-raised-button.mat-primary{color:rgba(0,0,0,.87)}.mat-fab.mat-accent[disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-flat-button.mat-accent[disabled],.mat-flat-button.mat-primary[disabled],.mat-flat-button.mat-warn[disabled],.mat-flat-button[disabled][disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.26);background-color:rgba(0,0,0,.12)}.mat-fab.mat-primary,.mat-flat-button.mat-primary,.mat-mini-fab.mat-primary,.mat-raised-button.mat-primary{background-color:#eceff1}.mat-fab.mat-accent,.mat-flat-button.mat-accent,.mat-mini-fab.mat-accent,.mat-raised-button.mat-accent{background-color:#ffc107}.mat-fab.mat-warn,.mat-flat-button.mat-warn,.mat-mini-fab.mat-warn,.mat-raised-button.mat-warn{color:#fff;background-color:#f44336}.mat-fab.mat-accent .mat-ripple-element,.mat-fab.mat-primary .mat-ripple-element,.mat-flat-button.mat-accent .mat-ripple-element,.mat-flat-button.mat-primary .mat-ripple-element,.mat-mini-fab.mat-accent .mat-ripple-element,.mat-mini-fab.mat-primary .mat-ripple-element,.mat-raised-button.mat-accent .mat-ripple-element,.mat-raised-button.mat-primary .mat-ripple-element{background-color:rgba(0,0,0,.1)}.mat-fab.mat-warn .mat-ripple-element,.mat-flat-button.mat-warn .mat-ripple-element,.mat-mini-fab.mat-warn .mat-ripple-element,.mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.1)}.mat-flat-button:not([class*=mat-elevation-z]),.mat-stroked-button:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.mat-raised-button[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-fab:not([class*=mat-elevation-z]),.mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-fab[disabled]:not([class*=mat-elevation-z]),.mat-mini-fab[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-button-toggle-group,.mat-button-toggle-standalone{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-button-toggle-group-appearance-standard,.mat-button-toggle-standalone.mat-button-toggle-appearance-standard{box-shadow:none;border:1px solid rgba(0,0,0,.12)}.mat-button-toggle{color:rgba(0,0,0,.38)}.mat-button-toggle .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.12)}.mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87);background:#fff}.mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay{background-color:#000}.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:1px solid rgba(0,0,0,.12)}[dir=rtl] .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.mat-button-toggle-group-appearance-standard.mat-button-toggle-vertical .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:none;border-top:1px solid rgba(0,0,0,.12)}.mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.mat-button-toggle-checked.mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87)}.mat-button-toggle-disabled{color:rgba(0,0,0,.26);background-color:#eee}.mat-button-toggle-disabled.mat-button-toggle-appearance-standard{background:#fff}.mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.mat-card{background:#fff;color:rgba(0,0,0,.87)}.mat-card:not([class*=mat-elevation-z]){box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.mat-card.mat-card-flat:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-card-subtitle{color:rgba(0,0,0,.54)}.mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.mat-checkbox-checkmark{fill:#fafafa}.mat-checkbox-checkmark-path{stroke:#fafafa!important}.mat-checkbox-mixedmark{background-color:#fafafa}.mat-checkbox-checked.mat-primary .mat-checkbox-background,.mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#eceff1}.mat-checkbox-checked.mat-accent .mat-checkbox-background,.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ffc107}.mat-checkbox-checked.mat-warn .mat-checkbox-background,.mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.mat-checkbox-disabled .mat-checkbox-label{color:rgba(0,0,0,.54)}@media (-ms-high-contrast:active){.mat-checkbox-background{background:0 0}.alternate-theme .mat-badge-content{outline:solid 1px;border-radius:0}}.mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:#eceff1}.mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:#ffc107}.mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:#f44336}.mat-chip.mat-standard-chip{background-color:#e0e0e0;color:rgba(0,0,0,.87)}.mat-chip.mat-standard-chip .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.mat-chip.mat-standard-chip:not(.mat-chip-disabled):active{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.mat-chip.mat-standard-chip:not(.mat-chip-disabled) .mat-chip-remove:hover{opacity:.54}.mat-chip.mat-standard-chip.mat-chip-disabled{opacity:.4}.mat-chip.mat-standard-chip::after{background:#000}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary{background-color:#eceff1;color:rgba(0,0,0,.87)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-ripple-element{background:rgba(0,0,0,.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-ripple-element{background:rgba(255,255,255,.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:#ffc107;color:rgba(0,0,0,.87)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-ripple-element{background:rgba(0,0,0,.1)}.mat-table{background:#fff}.mat-table tbody,.mat-table tfoot,.mat-table thead,.mat-table-sticky,[mat-footer-row],[mat-header-row],[mat-row],mat-footer-row,mat-header-row,mat-row{background:inherit}mat-footer-row,mat-header-row,mat-row,td.mat-cell,td.mat-footer-cell,th.mat-header-cell{border-bottom-color:rgba(0,0,0,.12)}.mat-header-cell{color:rgba(0,0,0,.54)}.mat-cell,.mat-footer-cell{color:rgba(0,0,0,.87)}.mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.mat-datepicker-content .mat-calendar-next-button,.mat-datepicker-content .mat-calendar-previous-button,.mat-datepicker-toggle{color:rgba(0,0,0,.54)}.mat-calendar-table-header{color:rgba(0,0,0,.38)}.mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.mat-calendar-body-label{color:rgba(0,0,0,.54)}.mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.mat-calendar-body-selected{background-color:#eceff1;color:rgba(0,0,0,.87)}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(236,239,241,.4)}.mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px rgba(0,0,0,.87)}.mat-datepicker-content{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);background-color:#fff;color:rgba(0,0,0,.87)}.mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:#ffc107;color:rgba(0,0,0,.87)}.mat-datepicker-content.mat-accent .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(255,193,7,.4)}.mat-datepicker-content.mat-accent .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px rgba(0,0,0,.87)}.mat-datepicker-content.mat-warn .mat-calendar-body-selected{background-color:#f44336;color:#fff}.mat-datepicker-content.mat-warn .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(244,67,54,.4)}.mat-datepicker-content.mat-warn .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content-touch{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-datepicker-toggle-active{color:#eceff1}.mat-datepicker-toggle-active.mat-accent{color:#ffc107}.mat-datepicker-toggle-active.mat-warn{color:#f44336}.mat-dialog-container{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.mat-divider{border-top-color:rgba(0,0,0,.12)}.mat-divider-vertical{border-right-color:rgba(0,0,0,.12)}.mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-action-row{border-top-color:rgba(0,0,0,.12)}.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}@media (hover:none){.mat-expansion-panel:not(.mat-expanded):not([aria-disabled=true]) .mat-expansion-panel-header:hover{background:#fff}}.mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.mat-expansion-indicator::after,.mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.26)}.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.mat-form-field-label,.mat-hint{color:rgba(0,0,0,.6)}.mat-form-field.mat-focused .mat-form-field-label{color:#eceff1}.mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:#ffc107}.mat-form-field.mat-focused .mat-form-field-label.mat-warn{color:#f44336}.mat-focused .mat-form-field-required-marker{color:#ffc107}.mat-form-field-ripple{background-color:rgba(0,0,0,.87)}.mat-form-field.mat-focused .mat-form-field-ripple{background-color:#eceff1}.mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:#ffc107}.mat-form-field.mat-focused .mat-form-field-ripple.mat-warn{background-color:#f44336}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid) .mat-form-field-infix::after{color:#eceff1}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:#ffc107}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-warn .mat-form-field-infix::after,.mat-form-field.mat-form-field-invalid .mat-form-field-label,.mat-form-field.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.mat-form-field.mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.mat-form-field.mat-form-field-invalid .mat-form-field-ripple,.mat-form-field.mat-form-field-invalid .mat-form-field-ripple.mat-accent{background-color:#f44336}.mat-error{color:#f44336}.mat-form-field-appearance-legacy .mat-form-field-label,.mat-form-field-appearance-legacy .mat-hint{color:rgba(0,0,0,.54)}.mat-form-field-appearance-legacy .mat-form-field-underline{bottom:1.25em;background-color:rgba(0,0,0,.42)}.mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-standard .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-fill .mat-form-field-flex{background-color:rgba(0,0,0,.04)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-flex{background-color:rgba(0,0,0,.02)}.mat-form-field-appearance-fill .mat-form-field-underline::before{background-color:rgba(0,0,0,.42)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-underline::before{background-color:transparent}.mat-form-field-appearance-outline .mat-form-field-outline{color:rgba(0,0,0,.12)}.mat-form-field-appearance-outline .mat-form-field-outline-thick{color:rgba(0,0,0,.87)}.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick{color:#eceff1}.mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:#ffc107}.mat-form-field-appearance-outline.mat-focused.mat-warn .mat-form-field-outline-thick,.mat-form-field-appearance-outline.mat-form-field-invalid.mat-form-field-invalid .mat-form-field-outline-thick{color:#f44336}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{color:rgba(0,0,0,.06)}.mat-icon.mat-primary{color:#eceff1}.mat-icon.mat-accent{color:#ffc107}.mat-icon.mat-warn{color:#f44336}.mat-form-field-type-mat-native-select .mat-form-field-infix::after{color:rgba(0,0,0,.54)}.mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after,.mat-input-element:disabled{color:rgba(0,0,0,.38)}.mat-input-element{caret-color:#eceff1}.mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-accent .mat-input-element{caret-color:#ffc107}.mat-form-field-invalid .mat-input-element,.mat-warn .mat-input-element{caret-color:#f44336}.mat-form-field-type-mat-native-select.mat-form-field-invalid .mat-form-field-infix::after{color:#f44336}.mat-list-base .mat-list-item,.mat-list-base .mat-list-option{color:rgba(0,0,0,.87)}.mat-list-base .mat-subheader{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500;color:rgba(0,0,0,.54)}.mat-list-item-disabled{background-color:#eee}.mat-action-list .mat-list-item:focus,.mat-action-list .mat-list-item:hover,.mat-list-option:focus,.mat-list-option:hover,.mat-nav-list .mat-list-item:focus,.mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.mat-menu-panel{background:#fff}.mat-menu-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.mat-menu-item[disabled],.mat-menu-item[disabled]::after{color:rgba(0,0,0,.38)}.mat-menu-item .mat-icon-no-color,.mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.mat-menu-item-highlighted:not([disabled]),.mat-menu-item.cdk-keyboard-focused:not([disabled]),.mat-menu-item.cdk-program-focused:not([disabled]),.mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.mat-paginator{background:#fff}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.mat-paginator-decrement,.mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.mat-paginator-first,.mat-paginator-last{border-top:2px solid rgba(0,0,0,.54)}.mat-icon-button[disabled] .mat-paginator-decrement,.mat-icon-button[disabled] .mat-paginator-first,.mat-icon-button[disabled] .mat-paginator-increment,.mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,.38)}.mat-progress-bar-background{fill:#90a4ae}.mat-progress-bar-buffer{background-color:#90a4ae}.mat-progress-bar-fill::after{background-color:#eceff1}.mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#ffa000}.mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#ffa000}.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ffc107}.mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.mat-progress-spinner circle,.mat-spinner circle{stroke:#eceff1}.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:#ffc107}.mat-progress-spinner.mat-warn circle,.mat-spinner.mat-warn circle{stroke:#f44336}.mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#eceff1}.mat-radio-button.mat-primary .mat-radio-inner-circle,.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-primary:active .mat-radio-persistent-ripple{background-color:#eceff1}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ffc107}.mat-radio-button.mat-accent .mat-radio-inner-circle,.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:#ffc107}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.mat-radio-button.mat-warn .mat-radio-inner-circle,.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-warn:active .mat-radio-persistent-ripple{background-color:#f44336}.mat-radio-button.mat-radio-disabled .mat-radio-outer-circle,.mat-radio-button.mat-radio-disabled.mat-radio-checked .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.mat-radio-button.mat-radio-disabled .mat-radio-inner-circle,.mat-radio-button.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.mat-radio-button.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.mat-radio-button .mat-ripple-element{background-color:#000}.mat-select-value{color:rgba(0,0,0,.87)}.mat-select-placeholder{color:rgba(0,0,0,.42)}.mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.mat-select-arrow{color:rgba(0,0,0,.54)}.mat-select-panel{background:#fff}.mat-select-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#eceff1}.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ffc107}.mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.mat-drawer.mat-drawer-push{background-color:#fff}.mat-drawer:not(.mat-drawer-side){box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.mat-drawer-side{border-right:1px solid rgba(0,0,0,.12)}.mat-drawer-side.mat-drawer-end,[dir=rtl] .mat-drawer-side{border-left:1px solid rgba(0,0,0,.12);border-right:none}[dir=rtl] .mat-drawer-side.mat-drawer-end{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:#ffc107}.mat-slide-toggle.mat-checked .mat-slide-toggle-bar{background-color:rgba(255,193,7,.54)}.mat-slide-toggle.mat-checked .mat-ripple-element{background-color:#ffc107}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb{background-color:#eceff1}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar{background-color:rgba(236,239,241,.54)}.mat-slide-toggle.mat-primary.mat-checked .mat-ripple-element{background-color:#eceff1}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-thumb{background-color:#f44336}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-bar{background-color:rgba(244,67,54,.54)}.mat-slide-toggle.mat-warn.mat-checked .mat-ripple-element{background-color:#f44336}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:#000}.mat-slide-toggle-thumb{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label,.mat-primary .mat-slider-track-fill{background-color:#eceff1}.mat-primary .mat-slider-thumb-label-text{color:rgba(0,0,0,.87)}.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label,.mat-accent .mat-slider-track-fill{background-color:#ffc107}.mat-accent .mat-slider-thumb-label-text{color:rgba(0,0,0,.87)}.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label,.mat-warn .mat-slider-track-fill{background-color:#f44336}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(255,193,7,.2)}.cdk-focused .mat-slider-track-background,.mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.mat-slider-disabled .mat-slider-thumb,.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-step-header.cdk-keyboard-focused,.mat-step-header.cdk-program-focused,.mat-step-header:hover{background-color:rgba(0,0,0,.04)}@media (hover:none){.mat-step-header:hover{background:0 0}}.mat-step-header .mat-step-label,.mat-step-header .mat-step-optional{color:rgba(0,0,0,.54)}.mat-step-header .mat-step-icon{background-color:rgba(0,0,0,.54);color:rgba(0,0,0,.87)}.mat-step-header .mat-step-icon-selected,.mat-step-header .mat-step-icon-state-done,.mat-step-header .mat-step-icon-state-edit{background-color:#eceff1;color:rgba(0,0,0,.87)}.mat-step-header .mat-step-icon-state-error{background-color:transparent;color:#f44336}.mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.mat-step-header .mat-step-label.mat-step-label-error{color:#f44336}.mat-stepper-horizontal,.mat-stepper-vertical{background-color:#fff}.mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.mat-horizontal-stepper-header::after,.mat-horizontal-stepper-header::before,.mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.mat-sort-header-arrow{color:#757575}.mat-tab-header,.mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.mat-tab-group-inverted-header .mat-tab-header,.mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.mat-tab-group[class*=mat-background-] .mat-tab-header,.mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.mat-tab-group.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(144,164,174,.3)}.mat-tab-group.mat-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#eceff1}.mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:rgba(0,0,0,.87)}.mat-tab-group.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,160,0,.3)}.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#ffc107}.mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:rgba(0,0,0,.87)}.mat-tab-group.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(144,164,174,.3)}.mat-tab-group.mat-background-primary .mat-tab-header,.mat-tab-group.mat-background-primary .mat-tab-links,.mat-tab-nav-bar.mat-background-primary .mat-tab-header,.mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#eceff1}.mat-tab-group.mat-background-primary .mat-tab-label,.mat-tab-group.mat-background-primary .mat-tab-link,.mat-tab-nav-bar.mat-background-primary .mat-tab-label,.mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.4)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.4)}.mat-tab-group.mat-background-primary .mat-ripple-element,.mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(0,0,0,.12)}.mat-tab-group.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,160,0,.3)}.mat-tab-group.mat-background-accent .mat-tab-header,.mat-tab-group.mat-background-accent .mat-tab-links,.mat-tab-nav-bar.mat-background-accent .mat-tab-header,.mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ffc107}.mat-tab-group.mat-background-accent .mat-tab-label,.mat-tab-group.mat-background-accent .mat-tab-link,.mat-tab-nav-bar.mat-background-accent .mat-tab-label,.mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.4)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.4)}.mat-tab-group.mat-background-accent .mat-ripple-element,.mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(0,0,0,.12)}.mat-tab-group.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-background-warn .mat-tab-header,.mat-tab-group.mat-background-warn .mat-tab-links,.mat-tab-nav-bar.mat-background-warn .mat-tab-header,.mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.mat-tab-group.mat-background-warn .mat-tab-label,.mat-tab-group.mat-background-warn .mat-tab-link,.mat-tab-nav-bar.mat-background-warn .mat-tab-label,.mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-ripple-element,.mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.mat-toolbar.mat-primary{background:#eceff1;color:rgba(0,0,0,.87)}.mat-toolbar.mat-accent{background:#ffc107;color:rgba(0,0,0,.87)}.mat-toolbar.mat-warn{background:#f44336;color:#fff}.mat-toolbar .mat-focused .mat-form-field-ripple,.mat-toolbar .mat-form-field-ripple,.mat-toolbar .mat-form-field-underline{background-color:currentColor}.mat-toolbar .mat-focused .mat-form-field-label,.mat-toolbar .mat-form-field-label,.mat-toolbar .mat-form-field.mat-focused .mat-select-arrow,.mat-toolbar .mat-select-arrow,.mat-toolbar .mat-select-value{color:inherit}.mat-toolbar .mat-input-element{caret-color:currentColor}.mat-tooltip{background:rgba(97,97,97,.9)}.mat-tree{font-family:Roboto,"Helvetica Neue",sans-serif;background:#fff}.mat-nested-tree-node,.mat-tree-node{font-weight:400;font-size:14px;color:rgba(0,0,0,.87)}.mat-snack-bar-container{color:rgba(255,255,255,.7);background:#323232;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-simple-snackbar-action{color:#ffc107}.alternate-theme .mat-ripple-element{background-color:rgba(0,0,0,.1)}.alternate-theme .mat-option{color:rgba(0,0,0,.87)}.alternate-theme .mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled),.alternate-theme .mat-option:focus:not(.mat-option-disabled),.alternate-theme .mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.alternate-theme .mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.alternate-theme .mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.alternate-theme .mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#424242}.alternate-theme .mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#bdbdbd}.alternate-theme .mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.alternate-theme .mat-optgroup-label{color:rgba(0,0,0,.54)}.alternate-theme .mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.alternate-theme .mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.alternate-theme .mat-pseudo-checkbox::after{color:#fafafa}.alternate-theme .mat-pseudo-checkbox-disabled{color:#b0b0b0}.alternate-theme .mat-accent .mat-pseudo-checkbox-checked,.alternate-theme .mat-accent .mat-pseudo-checkbox-indeterminate,.alternate-theme .mat-pseudo-checkbox-checked,.alternate-theme .mat-pseudo-checkbox-indeterminate{background:#bdbdbd}.alternate-theme .mat-primary .mat-pseudo-checkbox-checked,.alternate-theme .mat-primary .mat-pseudo-checkbox-indeterminate{background:#424242}.alternate-theme .mat-warn .mat-pseudo-checkbox-checked,.alternate-theme .mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.alternate-theme .mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.alternate-theme .mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.alternate-theme .mat-elevation-z0{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z1{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z2{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z3{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z4{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z5{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z6{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z7{box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z8{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z9{box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z10{box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z11{box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z12{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z13{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z14{box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z15{box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z16{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z17{box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z18{box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z19{box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z20{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z21{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z22{box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z23{box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12)}.alternate-theme .mat-elevation-z24{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}.alternate-theme .mat-app-background,.alternate-theme.mat-app-background{background-color:#fafafa;color:rgba(0,0,0,.87)}.alternate-theme .mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-autocomplete-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.alternate-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.alternate-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}.alternate-theme .mat-badge-accent .mat-badge-content{background:#bdbdbd;color:rgba(0,0,0,.87)}.alternate-theme .mat-badge-warn .mat-badge-content{color:#fff;background:#f44336}.alternate-theme .mat-badge{position:relative}.alternate-theme .mat-badge-hidden .mat-badge-content{display:none}.alternate-theme .mat-badge-disabled .mat-badge-content{background:#b9b9b9;color:rgba(0,0,0,.38)}.alternate-theme .mat-badge-content{color:#fff;background:#424242;position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;-webkit-transform:scale(.6);transform:scale(.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.alternate-theme .mat-badge-content.mat-badge-active{-webkit-transform:none;transform:none}.alternate-theme .mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.alternate-theme .mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.alternate-theme .mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.alternate-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir=rtl] .alternate-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.alternate-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir=rtl] .alternate-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.alternate-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir=rtl] .alternate-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.alternate-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir=rtl] .alternate-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.alternate-theme .mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.alternate-theme .mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.alternate-theme .mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.alternate-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir=rtl] .alternate-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.alternate-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir=rtl] .alternate-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.alternate-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir=rtl] .alternate-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.alternate-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir=rtl] .alternate-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.alternate-theme .mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.alternate-theme .mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.alternate-theme .mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.alternate-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir=rtl] .alternate-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.alternate-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir=rtl] .alternate-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.alternate-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir=rtl] .alternate-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.alternate-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir=rtl] .alternate-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.alternate-theme .mat-bottom-sheet-container{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-button,.alternate-theme .mat-icon-button,.alternate-theme .mat-stroked-button{color:inherit;background:0 0}.alternate-theme .mat-button.mat-primary,.alternate-theme .mat-icon-button.mat-primary,.alternate-theme .mat-stroked-button.mat-primary{color:#424242}.alternate-theme .mat-button.mat-accent,.alternate-theme .mat-icon-button.mat-accent,.alternate-theme .mat-stroked-button.mat-accent{color:#bdbdbd}.alternate-theme .mat-button.mat-warn,.alternate-theme .mat-icon-button.mat-warn,.alternate-theme .mat-stroked-button.mat-warn{color:#f44336}.alternate-theme .mat-button.mat-accent[disabled],.alternate-theme .mat-button.mat-primary[disabled],.alternate-theme .mat-button.mat-warn[disabled],.alternate-theme .mat-button[disabled][disabled],.alternate-theme .mat-icon-button.mat-accent[disabled],.alternate-theme .mat-icon-button.mat-primary[disabled],.alternate-theme .mat-icon-button.mat-warn[disabled],.alternate-theme .mat-icon-button[disabled][disabled],.alternate-theme .mat-stroked-button.mat-accent[disabled],.alternate-theme .mat-stroked-button.mat-primary[disabled],.alternate-theme .mat-stroked-button.mat-warn[disabled],.alternate-theme .mat-stroked-button[disabled][disabled]{color:rgba(0,0,0,.26)}.alternate-theme .mat-button.mat-primary .mat-button-focus-overlay,.alternate-theme .mat-icon-button.mat-primary .mat-button-focus-overlay,.alternate-theme .mat-stroked-button.mat-primary .mat-button-focus-overlay{background-color:#424242}.alternate-theme .mat-button.mat-accent .mat-button-focus-overlay,.alternate-theme .mat-icon-button.mat-accent .mat-button-focus-overlay,.alternate-theme .mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:#bdbdbd}.alternate-theme .mat-button.mat-warn .mat-button-focus-overlay,.alternate-theme .mat-icon-button.mat-warn .mat-button-focus-overlay,.alternate-theme .mat-stroked-button.mat-warn .mat-button-focus-overlay{background-color:#f44336}.alternate-theme .mat-button[disabled] .mat-button-focus-overlay,.alternate-theme .mat-icon-button[disabled] .mat-button-focus-overlay,.alternate-theme .mat-stroked-button[disabled] .mat-button-focus-overlay{background-color:transparent}.alternate-theme .mat-button .mat-ripple-element,.alternate-theme .mat-icon-button .mat-ripple-element,.alternate-theme .mat-stroked-button .mat-ripple-element{opacity:.1;background-color:currentColor}.alternate-theme .mat-button-focus-overlay{background:#000}.alternate-theme .mat-stroked-button:not([disabled]){border-color:rgba(0,0,0,.12)}.alternate-theme .mat-fab,.alternate-theme .mat-flat-button,.alternate-theme .mat-mini-fab,.alternate-theme .mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.alternate-theme .mat-fab.mat-primary,.alternate-theme .mat-flat-button.mat-primary,.alternate-theme .mat-mini-fab.mat-primary,.alternate-theme .mat-raised-button.mat-primary{color:#fff;background-color:#424242}.alternate-theme .mat-fab.mat-accent,.alternate-theme .mat-flat-button.mat-accent,.alternate-theme .mat-mini-fab.mat-accent,.alternate-theme .mat-raised-button.mat-accent{color:rgba(0,0,0,.87);background-color:#bdbdbd}.alternate-theme .mat-fab.mat-warn,.alternate-theme .mat-flat-button.mat-warn,.alternate-theme .mat-mini-fab.mat-warn,.alternate-theme .mat-raised-button.mat-warn{color:#fff;background-color:#f44336}.alternate-theme .mat-fab.mat-accent[disabled],.alternate-theme .mat-fab.mat-primary[disabled],.alternate-theme .mat-fab.mat-warn[disabled],.alternate-theme .mat-fab[disabled][disabled],.alternate-theme .mat-flat-button.mat-accent[disabled],.alternate-theme .mat-flat-button.mat-primary[disabled],.alternate-theme .mat-flat-button.mat-warn[disabled],.alternate-theme .mat-flat-button[disabled][disabled],.alternate-theme .mat-mini-fab.mat-accent[disabled],.alternate-theme .mat-mini-fab.mat-primary[disabled],.alternate-theme .mat-mini-fab.mat-warn[disabled],.alternate-theme .mat-mini-fab[disabled][disabled],.alternate-theme .mat-raised-button.mat-accent[disabled],.alternate-theme .mat-raised-button.mat-primary[disabled],.alternate-theme .mat-raised-button.mat-warn[disabled],.alternate-theme .mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.26);background-color:rgba(0,0,0,.12)}.alternate-theme .mat-fab.mat-primary .mat-ripple-element,.alternate-theme .mat-flat-button.mat-primary .mat-ripple-element,.alternate-theme .mat-mini-fab.mat-primary .mat-ripple-element,.alternate-theme .mat-raised-button.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,.1)}.alternate-theme .mat-fab.mat-accent .mat-ripple-element,.alternate-theme .mat-flat-button.mat-accent .mat-ripple-element,.alternate-theme .mat-mini-fab.mat-accent .mat-ripple-element,.alternate-theme .mat-raised-button.mat-accent .mat-ripple-element{background-color:rgba(0,0,0,.1)}.alternate-theme .mat-fab.mat-warn .mat-ripple-element,.alternate-theme .mat-flat-button.mat-warn .mat-ripple-element,.alternate-theme .mat-mini-fab.mat-warn .mat-ripple-element,.alternate-theme .mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.1)}.alternate-theme .mat-flat-button:not([class*=mat-elevation-z]),.alternate-theme .mat-stroked-button:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.alternate-theme .mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.alternate-theme .mat-raised-button[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-fab:not([class*=mat-elevation-z]),.alternate-theme .mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.alternate-theme .mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.alternate-theme .mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.alternate-theme .mat-fab[disabled]:not([class*=mat-elevation-z]),.alternate-theme .mat-mini-fab[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle-group,.alternate-theme .mat-button-toggle-standalone{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle-group-appearance-standard,.alternate-theme .mat-button-toggle-standalone.mat-button-toggle-appearance-standard{box-shadow:none;border:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle{color:rgba(0,0,0,.38)}.alternate-theme .mat-button-toggle .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87);background:#fff}.alternate-theme .mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay{background-color:#000}.alternate-theme .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:1px solid rgba(0,0,0,.12)}.alternate-theme [dir=rtl] .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle-group-appearance-standard.mat-button-toggle-vertical .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:none;border-top:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.alternate-theme .mat-button-toggle-checked.mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87)}.alternate-theme .mat-button-toggle-disabled{color:rgba(0,0,0,.26);background-color:#eee}.alternate-theme .mat-button-toggle-disabled.mat-button-toggle-appearance-standard{background:#fff}.alternate-theme .mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.alternate-theme .mat-card{background:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-card:not([class*=mat-elevation-z]){box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.alternate-theme .mat-card.mat-card-flat:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-card-subtitle{color:rgba(0,0,0,.54)}.alternate-theme .mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.alternate-theme .mat-checkbox-checkmark{fill:#fafafa}.alternate-theme .mat-checkbox-checkmark-path{stroke:#fafafa!important}@media (-ms-high-contrast:black-on-white){.alternate-theme .mat-checkbox-checkmark-path,.mat-checkbox-checkmark-path{stroke:#000!important}}.alternate-theme .mat-checkbox-mixedmark{background-color:#fafafa}.alternate-theme .mat-checkbox-checked.mat-primary .mat-checkbox-background,.alternate-theme .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#424242}.alternate-theme .mat-checkbox-checked.mat-accent .mat-checkbox-background,.alternate-theme .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#bdbdbd}.alternate-theme .mat-checkbox-checked.mat-warn .mat-checkbox-background,.alternate-theme .mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.alternate-theme .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.alternate-theme .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.alternate-theme .mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.alternate-theme .mat-checkbox-disabled .mat-checkbox-label{color:rgba(0,0,0,.54)}@media (-ms-high-contrast:active){.alternate-theme .mat-checkbox-disabled{opacity:.5}.alternate-theme .mat-checkbox-background{background:0 0}.volume-theme .mat-badge-content{outline:solid 1px;border-radius:0}}.alternate-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:#424242}.alternate-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:#bdbdbd}.alternate-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:#f44336}.alternate-theme .mat-chip.mat-standard-chip{background-color:#e0e0e0;color:rgba(0,0,0,.87)}.alternate-theme .mat-chip.mat-standard-chip .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.alternate-theme .mat-chip.mat-standard-chip:not(.mat-chip-disabled):active{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.alternate-theme .mat-chip.mat-standard-chip:not(.mat-chip-disabled) .mat-chip-remove:hover{opacity:.54}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-disabled{opacity:.4}.alternate-theme .mat-chip.mat-standard-chip::after{background:#000}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary{background-color:#424242;color:#fff}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#fff;opacity:.4}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-ripple-element{background:rgba(255,255,255,.1)}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-ripple-element{background:rgba(255,255,255,.1)}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:#bdbdbd;color:rgba(0,0,0,.87)}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.alternate-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-ripple-element{background:rgba(0,0,0,.1)}.alternate-theme .mat-table{background:#fff}.alternate-theme .mat-table tbody,.alternate-theme .mat-table tfoot,.alternate-theme .mat-table thead,.alternate-theme .mat-table-sticky,.alternate-theme [mat-footer-row],.alternate-theme [mat-header-row],.alternate-theme [mat-row],.alternate-theme mat-footer-row,.alternate-theme mat-header-row,.alternate-theme mat-row{background:inherit}.alternate-theme mat-footer-row,.alternate-theme mat-header-row,.alternate-theme mat-row,.alternate-theme td.mat-cell,.alternate-theme td.mat-footer-cell,.alternate-theme th.mat-header-cell{border-bottom-color:rgba(0,0,0,.12)}.alternate-theme .mat-header-cell{color:rgba(0,0,0,.54)}.alternate-theme .mat-cell,.alternate-theme .mat-footer-cell{color:rgba(0,0,0,.87)}.alternate-theme .mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.alternate-theme .mat-datepicker-content .mat-calendar-next-button,.alternate-theme .mat-datepicker-content .mat-calendar-previous-button,.alternate-theme .mat-datepicker-toggle{color:rgba(0,0,0,.54)}.alternate-theme .mat-calendar-table-header{color:rgba(0,0,0,.38)}.alternate-theme .mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.alternate-theme .mat-calendar-body-label{color:rgba(0,0,0,.54)}.alternate-theme .mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.alternate-theme .mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.alternate-theme .cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.alternate-theme .cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.alternate-theme .mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.alternate-theme .mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.alternate-theme .mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.alternate-theme .mat-calendar-body-selected{background-color:#424242;color:#fff}.alternate-theme .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(66,66,66,.4)}.alternate-theme .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.alternate-theme .mat-datepicker-content{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);background-color:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:#bdbdbd;color:rgba(0,0,0,.87)}.alternate-theme .mat-datepicker-content.mat-accent .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(189,189,189,.4)}.alternate-theme .mat-datepicker-content.mat-accent .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px rgba(0,0,0,.87)}.alternate-theme .mat-datepicker-content.mat-warn .mat-calendar-body-selected{background-color:#f44336;color:#fff}.alternate-theme .mat-datepicker-content.mat-warn .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(244,67,54,.4)}.alternate-theme .mat-datepicker-content.mat-warn .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.alternate-theme .mat-datepicker-content-touch{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.alternate-theme .mat-datepicker-toggle-active{color:#424242}.alternate-theme .mat-datepicker-toggle-active.mat-accent{color:#bdbdbd}.alternate-theme .mat-datepicker-toggle-active.mat-warn{color:#f44336}.alternate-theme .mat-dialog-container{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-divider{border-top-color:rgba(0,0,0,.12)}.alternate-theme .mat-divider-vertical{border-right-color:rgba(0,0,0,.12)}.alternate-theme .mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.alternate-theme .mat-action-row{border-top-color:rgba(0,0,0,.12)}.alternate-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.alternate-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.alternate-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}@media (hover:none){.alternate-theme .mat-expansion-panel:not(.mat-expanded):not([aria-disabled=true]) .mat-expansion-panel-header:hover{background:#fff}}.alternate-theme .mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.alternate-theme .mat-expansion-indicator::after,.alternate-theme .mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.alternate-theme .mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.26)}.alternate-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.alternate-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.alternate-theme .mat-form-field-label,.alternate-theme .mat-hint{color:rgba(0,0,0,.6)}.alternate-theme .mat-form-field.mat-focused .mat-form-field-label{color:#424242}.alternate-theme .mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:#bdbdbd}.alternate-theme .mat-form-field.mat-focused .mat-form-field-label.mat-warn{color:#f44336}.alternate-theme .mat-focused .mat-form-field-required-marker{color:#bdbdbd}.alternate-theme .mat-form-field-ripple{background-color:rgba(0,0,0,.87)}.alternate-theme .mat-form-field.mat-focused .mat-form-field-ripple{background-color:#424242}.alternate-theme .mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:#bdbdbd}.alternate-theme .mat-form-field.mat-focused .mat-form-field-ripple.mat-warn{background-color:#f44336}.alternate-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid) .mat-form-field-infix::after{color:#424242}.alternate-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:#bdbdbd}.alternate-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-warn .mat-form-field-infix::after,.alternate-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label,.alternate-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.alternate-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.alternate-theme .mat-form-field.mat-form-field-invalid .mat-form-field-ripple,.alternate-theme .mat-form-field.mat-form-field-invalid .mat-form-field-ripple.mat-accent{background-color:#f44336}.alternate-theme .mat-error{color:#f44336}.alternate-theme .mat-form-field-appearance-legacy .mat-form-field-label,.alternate-theme .mat-form-field-appearance-legacy .mat-hint{color:rgba(0,0,0,.54)}.alternate-theme .mat-form-field-appearance-legacy .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.alternate-theme .mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.alternate-theme .mat-form-field-appearance-standard .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.alternate-theme .mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.alternate-theme .mat-form-field-appearance-fill .mat-form-field-flex{background-color:rgba(0,0,0,.04)}.alternate-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-flex{background-color:rgba(0,0,0,.02)}.alternate-theme .mat-form-field-appearance-fill .mat-form-field-underline::before{background-color:rgba(0,0,0,.42)}.alternate-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.alternate-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-underline::before{background-color:transparent}.alternate-theme .mat-form-field-appearance-outline .mat-form-field-outline{color:rgba(0,0,0,.12)}.alternate-theme .mat-form-field-appearance-outline .mat-form-field-outline-thick{color:rgba(0,0,0,.87)}.alternate-theme .mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick{color:#424242}.alternate-theme .mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:#bdbdbd}.alternate-theme .mat-form-field-appearance-outline.mat-focused.mat-warn .mat-form-field-outline-thick,.alternate-theme .mat-form-field-appearance-outline.mat-form-field-invalid.mat-form-field-invalid .mat-form-field-outline-thick{color:#f44336}.alternate-theme .mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.alternate-theme .mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{color:rgba(0,0,0,.06)}.alternate-theme .mat-icon.mat-primary{color:#424242}.alternate-theme .mat-icon.mat-accent{color:#bdbdbd}.alternate-theme .mat-icon.mat-warn{color:#f44336}.alternate-theme .mat-form-field-type-mat-native-select .mat-form-field-infix::after{color:rgba(0,0,0,.54)}.alternate-theme .mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after,.alternate-theme .mat-input-element:disabled{color:rgba(0,0,0,.38)}.alternate-theme .mat-input-element{caret-color:#424242}.alternate-theme .mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-input-element::placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-accent .mat-input-element{caret-color:#bdbdbd}.alternate-theme .mat-form-field-invalid .mat-input-element,.alternate-theme .mat-warn .mat-input-element{caret-color:#f44336}.alternate-theme .mat-form-field-type-mat-native-select.mat-form-field-invalid .mat-form-field-infix::after{color:#f44336}.alternate-theme .mat-list-base .mat-list-item,.alternate-theme .mat-list-base .mat-list-option{color:rgba(0,0,0,.87)}.alternate-theme .mat-list-base .mat-subheader{color:rgba(0,0,0,.54)}.alternate-theme .mat-list-item-disabled{background-color:#eee}.alternate-theme .mat-action-list .mat-list-item:focus,.alternate-theme .mat-action-list .mat-list-item:hover,.alternate-theme .mat-list-option:focus,.alternate-theme .mat-list-option:hover,.alternate-theme .mat-nav-list .mat-list-item:focus,.alternate-theme .mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.alternate-theme .mat-menu-panel{background:#fff}.alternate-theme .mat-menu-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.alternate-theme .mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.alternate-theme .mat-menu-item[disabled],.alternate-theme .mat-menu-item[disabled]::after{color:rgba(0,0,0,.38)}.alternate-theme .mat-menu-item .mat-icon-no-color,.alternate-theme .mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.alternate-theme .mat-menu-item-highlighted:not([disabled]),.alternate-theme .mat-menu-item.cdk-keyboard-focused:not([disabled]),.alternate-theme .mat-menu-item.cdk-program-focused:not([disabled]),.alternate-theme .mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.alternate-theme .mat-paginator{background:#fff}.alternate-theme .mat-paginator,.alternate-theme .mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.alternate-theme .mat-paginator-decrement,.alternate-theme .mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.alternate-theme .mat-paginator-first,.alternate-theme .mat-paginator-last{border-top:2px solid rgba(0,0,0,.54)}.alternate-theme .mat-icon-button[disabled] .mat-paginator-decrement,.alternate-theme .mat-icon-button[disabled] .mat-paginator-first,.alternate-theme .mat-icon-button[disabled] .mat-paginator-increment,.alternate-theme .mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,.38)}.alternate-theme .mat-progress-bar-background{fill:#f5f5f5}.alternate-theme .mat-progress-bar-buffer{background-color:#f5f5f5}.alternate-theme .mat-progress-bar-fill::after{background-color:#424242}.alternate-theme .mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#f5f5f5}.alternate-theme .mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#f5f5f5}.alternate-theme .mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#bdbdbd}.alternate-theme .mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#ffcdd2}.alternate-theme .mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.alternate-theme .mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.alternate-theme .mat-progress-spinner circle,.alternate-theme .mat-spinner circle{stroke:#424242}.alternate-theme .mat-progress-spinner.mat-accent circle,.alternate-theme .mat-spinner.mat-accent circle{stroke:#bdbdbd}.alternate-theme .mat-progress-spinner.mat-warn circle,.alternate-theme .mat-spinner.mat-warn circle{stroke:#f44336}.alternate-theme .mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.alternate-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#424242}.alternate-theme .mat-radio-button.mat-primary .mat-radio-inner-circle,.alternate-theme .mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.alternate-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple,.alternate-theme .mat-radio-button.mat-primary:active .mat-radio-persistent-ripple{background-color:#424242}.alternate-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#bdbdbd}.alternate-theme .mat-radio-button.mat-accent .mat-radio-inner-circle,.alternate-theme .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.alternate-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.alternate-theme .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:#bdbdbd}.alternate-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.alternate-theme .mat-radio-button.mat-warn .mat-radio-inner-circle,.alternate-theme .mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.alternate-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-persistent-ripple,.alternate-theme .mat-radio-button.mat-warn:active .mat-radio-persistent-ripple{background-color:#f44336}.alternate-theme .mat-radio-button.mat-radio-disabled .mat-radio-outer-circle,.alternate-theme .mat-radio-button.mat-radio-disabled.mat-radio-checked .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.alternate-theme .mat-radio-button.mat-radio-disabled .mat-radio-inner-circle,.alternate-theme .mat-radio-button.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.alternate-theme .mat-radio-button.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.alternate-theme .mat-radio-button .mat-ripple-element{background-color:#000}.alternate-theme .mat-select-value{color:rgba(0,0,0,.87)}.alternate-theme .mat-select-placeholder{color:rgba(0,0,0,.42)}.alternate-theme .mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.alternate-theme .mat-select-arrow{color:rgba(0,0,0,.54)}.alternate-theme .mat-select-panel{background:#fff}.alternate-theme .mat-select-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.alternate-theme .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.alternate-theme .mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#424242}.alternate-theme .mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#bdbdbd}.alternate-theme .mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.alternate-theme .mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.alternate-theme .mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.alternate-theme .mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.alternate-theme .mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.alternate-theme .mat-drawer.mat-drawer-push{background-color:#fff}.alternate-theme .mat-drawer:not(.mat-drawer-side){box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.alternate-theme .mat-drawer-side{border-right:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-drawer-side.mat-drawer-end,.alternate-theme [dir=rtl] .mat-drawer-side{border-left:1px solid rgba(0,0,0,.12);border-right:none}.alternate-theme [dir=rtl] .mat-drawer-side.mat-drawer-end{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.alternate-theme .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:#bdbdbd}.alternate-theme .mat-slide-toggle.mat-checked .mat-slide-toggle-bar{background-color:rgba(189,189,189,.54)}.alternate-theme .mat-slide-toggle.mat-checked .mat-ripple-element{background-color:#bdbdbd}.alternate-theme .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb{background-color:#424242}.alternate-theme .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar{background-color:rgba(66,66,66,.54)}.alternate-theme .mat-slide-toggle.mat-primary.mat-checked .mat-ripple-element{background-color:#424242}.alternate-theme .mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-thumb{background-color:#f44336}.alternate-theme .mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-bar{background-color:rgba(244,67,54,.54)}.alternate-theme .mat-slide-toggle.mat-warn.mat-checked .mat-ripple-element{background-color:#f44336}.alternate-theme .mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:#000}.alternate-theme .mat-slide-toggle-thumb{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);background-color:#fafafa}.alternate-theme .mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.alternate-theme .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.alternate-theme .mat-primary .mat-slider-thumb,.alternate-theme .mat-primary .mat-slider-thumb-label,.alternate-theme .mat-primary .mat-slider-track-fill{background-color:#424242}.alternate-theme .mat-primary .mat-slider-thumb-label-text{color:#fff}.alternate-theme .mat-accent .mat-slider-thumb,.alternate-theme .mat-accent .mat-slider-thumb-label,.alternate-theme .mat-accent .mat-slider-track-fill{background-color:#bdbdbd}.alternate-theme .mat-accent .mat-slider-thumb-label-text{color:rgba(0,0,0,.87)}.alternate-theme .mat-warn .mat-slider-thumb,.alternate-theme .mat-warn .mat-slider-thumb-label,.alternate-theme .mat-warn .mat-slider-track-fill{background-color:#f44336}.alternate-theme .mat-warn .mat-slider-thumb-label-text{color:#fff}.alternate-theme .mat-slider-focus-ring{background-color:rgba(189,189,189,.2)}.alternate-theme .cdk-focused .mat-slider-track-background,.alternate-theme .mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.alternate-theme .mat-slider-disabled .mat-slider-thumb,.alternate-theme .mat-slider-disabled .mat-slider-track-background,.alternate-theme .mat-slider-disabled .mat-slider-track-fill,.alternate-theme .mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.alternate-theme .mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.alternate-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.alternate-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.alternate-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.alternate-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.alternate-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.alternate-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.alternate-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.alternate-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.alternate-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.alternate-theme .mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.alternate-theme .mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.alternate-theme .mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.alternate-theme .mat-step-header.cdk-keyboard-focused,.alternate-theme .mat-step-header.cdk-program-focused,.alternate-theme .mat-step-header:hover{background-color:rgba(0,0,0,.04)}@media (hover:none){.alternate-theme .mat-step-header:hover{background:0 0}}.alternate-theme .mat-step-header .mat-step-label,.alternate-theme .mat-step-header .mat-step-optional{color:rgba(0,0,0,.54)}.alternate-theme .mat-step-header .mat-step-icon{background-color:rgba(0,0,0,.54);color:#fff}.alternate-theme .mat-step-header .mat-step-icon-selected,.alternate-theme .mat-step-header .mat-step-icon-state-done,.alternate-theme .mat-step-header .mat-step-icon-state-edit{background-color:#424242;color:#fff}.alternate-theme .mat-step-header .mat-step-icon-state-error{background-color:transparent;color:#f44336}.alternate-theme .mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.alternate-theme .mat-step-header .mat-step-label.mat-step-label-error{color:#f44336}.alternate-theme .mat-stepper-horizontal,.alternate-theme .mat-stepper-vertical{background-color:#fff}.alternate-theme .mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.alternate-theme .mat-horizontal-stepper-header::after,.alternate-theme .mat-horizontal-stepper-header::before,.alternate-theme .mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.alternate-theme .mat-sort-header-arrow{color:#757575}.alternate-theme .mat-tab-header,.alternate-theme .mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.alternate-theme .mat-tab-group-inverted-header .mat-tab-header,.alternate-theme .mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.alternate-theme .mat-tab-label,.alternate-theme .mat-tab-link{color:rgba(0,0,0,.87)}.alternate-theme .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.alternate-theme .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.alternate-theme .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.alternate-theme .mat-tab-group[class*=mat-background-] .mat-tab-header,.alternate-theme .mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.alternate-theme .mat-tab-group.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(245,245,245,.3)}.alternate-theme .mat-tab-group.mat-primary .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#424242}.alternate-theme .mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.alternate-theme .mat-tab-group.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(245,245,245,.3)}.alternate-theme .mat-tab-group.mat-accent .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#bdbdbd}.alternate-theme .mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:rgba(0,0,0,.87)}.alternate-theme .mat-tab-group.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.alternate-theme .mat-tab-group.mat-warn .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.alternate-theme .mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.alternate-theme .mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(245,245,245,.3)}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-header,.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-links,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#424242}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-label,.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-link,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.alternate-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.alternate-theme .mat-tab-group.mat-background-primary .mat-ripple-element,.alternate-theme .mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,.12)}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(245,245,245,.3)}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-header,.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-links,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#bdbdbd}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-label,.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-link,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:rgba(0,0,0,.87)}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.4)}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.alternate-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.4)}.alternate-theme .mat-tab-group.mat-background-accent .mat-ripple-element,.alternate-theme .mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(0,0,0,.12)}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-header,.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-links,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-label,.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-link,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.alternate-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.alternate-theme .mat-tab-group.mat-background-warn .mat-ripple-element,.alternate-theme .mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.alternate-theme .mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.alternate-theme .mat-toolbar.mat-primary{background:#424242;color:#fff}.alternate-theme .mat-toolbar.mat-accent{background:#bdbdbd;color:rgba(0,0,0,.87)}.alternate-theme .mat-toolbar.mat-warn{background:#f44336;color:#fff}.alternate-theme .mat-toolbar .mat-focused .mat-form-field-ripple,.alternate-theme .mat-toolbar .mat-form-field-ripple,.alternate-theme .mat-toolbar .mat-form-field-underline{background-color:currentColor}.alternate-theme .mat-toolbar .mat-focused .mat-form-field-label,.alternate-theme .mat-toolbar .mat-form-field-label,.alternate-theme .mat-toolbar .mat-form-field.mat-focused .mat-select-arrow,.alternate-theme .mat-toolbar .mat-select-arrow,.alternate-theme .mat-toolbar .mat-select-value{color:inherit}.alternate-theme .mat-toolbar .mat-input-element{caret-color:currentColor}.alternate-theme .mat-tooltip{background:rgba(97,97,97,.9)}.alternate-theme .mat-tree{background:#fff}.alternate-theme .mat-nested-tree-node,.alternate-theme .mat-tree-node{color:rgba(0,0,0,.87)}.alternate-theme .mat-snack-bar-container{color:rgba(255,255,255,.7);background:#323232;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.alternate-theme .mat-simple-snackbar-action{color:#bdbdbd}.volume-theme .mat-ripple-element{background-color:rgba(0,0,0,.1)}.volume-theme .mat-option{color:rgba(0,0,0,.87)}.volume-theme .mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled),.volume-theme .mat-option:focus:not(.mat-option-disabled),.volume-theme .mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.volume-theme .mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.volume-theme .mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.volume-theme .mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#76ff03}.volume-theme .mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#ffc107}.volume-theme .mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.volume-theme .mat-optgroup-label{color:rgba(0,0,0,.54)}.volume-theme .mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.volume-theme .mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.volume-theme .mat-pseudo-checkbox::after{color:#fafafa}.volume-theme .mat-pseudo-checkbox-disabled{color:#b0b0b0}.volume-theme .mat-accent .mat-pseudo-checkbox-checked,.volume-theme .mat-accent .mat-pseudo-checkbox-indeterminate,.volume-theme .mat-pseudo-checkbox-checked,.volume-theme .mat-pseudo-checkbox-indeterminate{background:#ffc107}.volume-theme .mat-primary .mat-pseudo-checkbox-checked,.volume-theme .mat-primary .mat-pseudo-checkbox-indeterminate{background:#76ff03}.volume-theme .mat-warn .mat-pseudo-checkbox-checked,.volume-theme .mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.volume-theme .mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.volume-theme .mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.volume-theme .mat-elevation-z0{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z1{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z2{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z3{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z4{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z5{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z6{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.volume-theme .mat-elevation-z7{box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z8{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z9{box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z10{box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z11{box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z12{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z13{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z14{box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z15{box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z16{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z17{box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z18{box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z19{box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z20{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z21{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z22{box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z23{box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12)}.volume-theme .mat-elevation-z24{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}.volume-theme .mat-app-background,.volume-theme.mat-app-background{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-theme-loaded-marker{display:none}.volume-theme .mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-autocomplete-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.volume-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.volume-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}.volume-theme .mat-badge-accent .mat-badge-content{background:#ffc107;color:rgba(0,0,0,.87)}.volume-theme .mat-badge-warn .mat-badge-content{color:#fff;background:#f44336}.volume-theme .mat-badge{position:relative}.volume-theme .mat-badge-hidden .mat-badge-content{display:none}.volume-theme .mat-badge-disabled .mat-badge-content{background:#b9b9b9;color:rgba(0,0,0,.38)}.volume-theme .mat-badge-content{color:rgba(0,0,0,.87);background:#76ff03;position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;-webkit-transform:scale(.6);transform:scale(.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.volume-theme .mat-badge-content.mat-badge-active{-webkit-transform:none;transform:none}.volume-theme .mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.volume-theme .mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.volume-theme .mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.volume-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir=rtl] .volume-theme .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.volume-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir=rtl] .volume-theme .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.volume-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir=rtl] .volume-theme .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.volume-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir=rtl] .volume-theme .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.volume-theme .mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.volume-theme .mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.volume-theme .mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.volume-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir=rtl] .volume-theme .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.volume-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir=rtl] .volume-theme .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.volume-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir=rtl] .volume-theme .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.volume-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir=rtl] .volume-theme .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.volume-theme .mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.volume-theme .mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.volume-theme .mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.volume-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir=rtl] .volume-theme .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.volume-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir=rtl] .volume-theme .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.volume-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir=rtl] .volume-theme .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.volume-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir=rtl] .volume-theme .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.volume-theme .mat-bottom-sheet-container{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-button,.volume-theme .mat-icon-button,.volume-theme .mat-stroked-button{color:inherit;background:0 0}.volume-theme .mat-button.mat-primary,.volume-theme .mat-icon-button.mat-primary,.volume-theme .mat-stroked-button.mat-primary{color:#76ff03}.volume-theme .mat-button.mat-accent,.volume-theme .mat-icon-button.mat-accent,.volume-theme .mat-stroked-button.mat-accent{color:#ffc107}.volume-theme .mat-button.mat-warn,.volume-theme .mat-icon-button.mat-warn,.volume-theme .mat-stroked-button.mat-warn{color:#f44336}.volume-theme .mat-button.mat-accent[disabled],.volume-theme .mat-button.mat-primary[disabled],.volume-theme .mat-button.mat-warn[disabled],.volume-theme .mat-button[disabled][disabled],.volume-theme .mat-icon-button.mat-accent[disabled],.volume-theme .mat-icon-button.mat-primary[disabled],.volume-theme .mat-icon-button.mat-warn[disabled],.volume-theme .mat-icon-button[disabled][disabled],.volume-theme .mat-stroked-button.mat-accent[disabled],.volume-theme .mat-stroked-button.mat-primary[disabled],.volume-theme .mat-stroked-button.mat-warn[disabled],.volume-theme .mat-stroked-button[disabled][disabled]{color:rgba(0,0,0,.26)}.volume-theme .mat-button.mat-primary .mat-button-focus-overlay,.volume-theme .mat-icon-button.mat-primary .mat-button-focus-overlay,.volume-theme .mat-stroked-button.mat-primary .mat-button-focus-overlay{background-color:#76ff03}.volume-theme .mat-button.mat-accent .mat-button-focus-overlay,.volume-theme .mat-icon-button.mat-accent .mat-button-focus-overlay,.volume-theme .mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:#ffc107}.volume-theme .mat-button.mat-warn .mat-button-focus-overlay,.volume-theme .mat-icon-button.mat-warn .mat-button-focus-overlay,.volume-theme .mat-stroked-button.mat-warn .mat-button-focus-overlay{background-color:#f44336}.volume-theme .mat-button[disabled] .mat-button-focus-overlay,.volume-theme .mat-icon-button[disabled] .mat-button-focus-overlay,.volume-theme .mat-stroked-button[disabled] .mat-button-focus-overlay{background-color:transparent}.volume-theme .mat-button .mat-ripple-element,.volume-theme .mat-icon-button .mat-ripple-element,.volume-theme .mat-stroked-button .mat-ripple-element{opacity:.1;background-color:currentColor}.volume-theme .mat-button-focus-overlay{background:#000}.volume-theme .mat-stroked-button:not([disabled]){border-color:rgba(0,0,0,.12)}.volume-theme .mat-fab,.volume-theme .mat-flat-button,.volume-theme .mat-mini-fab,.volume-theme .mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.volume-theme .mat-fab.mat-accent,.volume-theme .mat-fab.mat-primary,.volume-theme .mat-flat-button.mat-accent,.volume-theme .mat-flat-button.mat-primary,.volume-theme .mat-mini-fab.mat-accent,.volume-theme .mat-mini-fab.mat-primary,.volume-theme .mat-raised-button.mat-accent,.volume-theme .mat-raised-button.mat-primary{color:rgba(0,0,0,.87)}.volume-theme .mat-fab.mat-accent[disabled],.volume-theme .mat-fab.mat-primary[disabled],.volume-theme .mat-fab.mat-warn[disabled],.volume-theme .mat-fab[disabled][disabled],.volume-theme .mat-flat-button.mat-accent[disabled],.volume-theme .mat-flat-button.mat-primary[disabled],.volume-theme .mat-flat-button.mat-warn[disabled],.volume-theme .mat-flat-button[disabled][disabled],.volume-theme .mat-mini-fab.mat-accent[disabled],.volume-theme .mat-mini-fab.mat-primary[disabled],.volume-theme .mat-mini-fab.mat-warn[disabled],.volume-theme .mat-mini-fab[disabled][disabled],.volume-theme .mat-raised-button.mat-accent[disabled],.volume-theme .mat-raised-button.mat-primary[disabled],.volume-theme .mat-raised-button.mat-warn[disabled],.volume-theme .mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.26);background-color:rgba(0,0,0,.12)}.volume-theme .mat-fab.mat-primary,.volume-theme .mat-flat-button.mat-primary,.volume-theme .mat-mini-fab.mat-primary,.volume-theme .mat-raised-button.mat-primary{background-color:#76ff03}.volume-theme .mat-fab.mat-accent,.volume-theme .mat-flat-button.mat-accent,.volume-theme .mat-mini-fab.mat-accent,.volume-theme .mat-raised-button.mat-accent{background-color:#ffc107}.volume-theme .mat-fab.mat-warn,.volume-theme .mat-flat-button.mat-warn,.volume-theme .mat-mini-fab.mat-warn,.volume-theme .mat-raised-button.mat-warn{color:#fff;background-color:#f44336}.volume-theme .mat-fab.mat-accent .mat-ripple-element,.volume-theme .mat-fab.mat-primary .mat-ripple-element,.volume-theme .mat-flat-button.mat-accent .mat-ripple-element,.volume-theme .mat-flat-button.mat-primary .mat-ripple-element,.volume-theme .mat-mini-fab.mat-accent .mat-ripple-element,.volume-theme .mat-mini-fab.mat-primary .mat-ripple-element,.volume-theme .mat-raised-button.mat-accent .mat-ripple-element,.volume-theme .mat-raised-button.mat-primary .mat-ripple-element{background-color:rgba(0,0,0,.1)}.volume-theme .mat-fab.mat-warn .mat-ripple-element,.volume-theme .mat-flat-button.mat-warn .mat-ripple-element,.volume-theme .mat-mini-fab.mat-warn .mat-ripple-element,.volume-theme .mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.1)}.volume-theme .mat-flat-button:not([class*=mat-elevation-z]),.volume-theme .mat-stroked-button:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.volume-theme .mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.volume-theme .mat-raised-button[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-fab:not([class*=mat-elevation-z]),.volume-theme .mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.volume-theme .mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.volume-theme .mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.volume-theme .mat-fab[disabled]:not([class*=mat-elevation-z]),.volume-theme .mat-mini-fab[disabled]:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-button-toggle-group,.volume-theme .mat-button-toggle-standalone{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.volume-theme .mat-button-toggle-group-appearance-standard,.volume-theme .mat-button-toggle-standalone.mat-button-toggle-appearance-standard{box-shadow:none;border:1px solid rgba(0,0,0,.12)}.volume-theme .mat-button-toggle{color:rgba(0,0,0,.38)}.volume-theme .mat-button-toggle .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.12)}.volume-theme .mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87);background:#fff}.volume-theme .mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay{background-color:#000}.volume-theme .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:1px solid rgba(0,0,0,.12)}.volume-theme [dir=rtl] .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.volume-theme .mat-button-toggle-group-appearance-standard.mat-button-toggle-vertical .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:none;border-top:1px solid rgba(0,0,0,.12)}.volume-theme .mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.volume-theme .mat-button-toggle-checked.mat-button-toggle-appearance-standard{color:rgba(0,0,0,.87)}.volume-theme .mat-button-toggle-disabled{color:rgba(0,0,0,.26);background-color:#eee}.volume-theme .mat-button-toggle-disabled.mat-button-toggle-appearance-standard{background:#fff}.volume-theme .mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.volume-theme .mat-card{background:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-card:not([class*=mat-elevation-z]){box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.volume-theme .mat-card.mat-card-flat:not([class*=mat-elevation-z]){box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-card-subtitle{color:rgba(0,0,0,.54)}.volume-theme .mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.volume-theme .mat-checkbox-checkmark{fill:#fafafa}.volume-theme .mat-checkbox-checkmark-path{stroke:#fafafa!important}@media (-ms-high-contrast:black-on-white){.volume-theme .mat-checkbox-checkmark-path{stroke:#000!important}}.volume-theme .mat-checkbox-mixedmark{background-color:#fafafa}.volume-theme .mat-checkbox-checked.mat-primary .mat-checkbox-background,.volume-theme .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#76ff03}.volume-theme .mat-checkbox-checked.mat-accent .mat-checkbox-background,.volume-theme .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ffc107}.volume-theme .mat-checkbox-checked.mat-warn .mat-checkbox-background,.volume-theme .mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.volume-theme .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.volume-theme .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.volume-theme .mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.volume-theme .mat-checkbox-disabled .mat-checkbox-label{color:rgba(0,0,0,.54)}@media (-ms-high-contrast:active){.volume-theme .mat-checkbox-disabled{opacity:.5}.volume-theme .mat-checkbox-background{background:0 0}}.volume-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:#76ff03}.volume-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:#ffc107}.volume-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:#f44336}.volume-theme .mat-chip.mat-standard-chip{background-color:#e0e0e0;color:rgba(0,0,0,.87)}.volume-theme .mat-chip.mat-standard-chip .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.volume-theme .mat-chip.mat-standard-chip:not(.mat-chip-disabled):active{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.volume-theme .mat-chip.mat-standard-chip:not(.mat-chip-disabled) .mat-chip-remove:hover{opacity:.54}.volume-theme .mat-chip.mat-standard-chip.mat-chip-disabled{opacity:.4}.volume-theme .mat-chip.mat-standard-chip::after{background:#000}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary{background-color:#76ff03;color:rgba(0,0,0,.87)}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-ripple-element{background:rgba(0,0,0,.1)}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-ripple-element{background:rgba(255,255,255,.1)}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:#ffc107;color:rgba(0,0,0,.87)}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.volume-theme .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-ripple-element{background:rgba(0,0,0,.1)}.volume-theme .mat-table{background:#fff}.volume-theme .mat-table tbody,.volume-theme .mat-table tfoot,.volume-theme .mat-table thead,.volume-theme .mat-table-sticky,.volume-theme [mat-footer-row],.volume-theme [mat-header-row],.volume-theme [mat-row],.volume-theme mat-footer-row,.volume-theme mat-header-row,.volume-theme mat-row{background:inherit}.volume-theme mat-footer-row,.volume-theme mat-header-row,.volume-theme mat-row,.volume-theme td.mat-cell,.volume-theme td.mat-footer-cell,.volume-theme th.mat-header-cell{border-bottom-color:rgba(0,0,0,.12)}.volume-theme .mat-header-cell{color:rgba(0,0,0,.54)}.volume-theme .mat-cell,.volume-theme .mat-footer-cell{color:rgba(0,0,0,.87)}.volume-theme .mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.volume-theme .mat-datepicker-content .mat-calendar-next-button,.volume-theme .mat-datepicker-content .mat-calendar-previous-button,.volume-theme .mat-datepicker-toggle{color:rgba(0,0,0,.54)}.volume-theme .mat-calendar-table-header{color:rgba(0,0,0,.38)}.volume-theme .mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.volume-theme .mat-calendar-body-label{color:rgba(0,0,0,.54)}.volume-theme .mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.volume-theme .mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.volume-theme .cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.volume-theme .cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.volume-theme .mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.volume-theme .mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.volume-theme .mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.volume-theme .mat-calendar-body-selected{background-color:#76ff03;color:rgba(0,0,0,.87)}.volume-theme .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(118,255,3,.4)}.volume-theme .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px rgba(0,0,0,.87)}.volume-theme .mat-datepicker-content{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);background-color:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:#ffc107;color:rgba(0,0,0,.87)}.volume-theme .mat-datepicker-content.mat-accent .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(255,193,7,.4)}.volume-theme .mat-datepicker-content.mat-accent .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px rgba(0,0,0,.87)}.volume-theme .mat-datepicker-content.mat-warn .mat-calendar-body-selected{background-color:#f44336;color:#fff}.volume-theme .mat-datepicker-content.mat-warn .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(244,67,54,.4)}.volume-theme .mat-datepicker-content.mat-warn .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.volume-theme .mat-datepicker-content-touch{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.volume-theme .mat-datepicker-toggle-active{color:#76ff03}.volume-theme .mat-datepicker-toggle-active.mat-accent{color:#ffc107}.volume-theme .mat-datepicker-toggle-active.mat-warn{color:#f44336}.volume-theme .mat-dialog-container{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);background:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-divider{border-top-color:rgba(0,0,0,.12)}.volume-theme .mat-divider-vertical{border-right-color:rgba(0,0,0,.12)}.volume-theme .mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.volume-theme .mat-action-row{border-top-color:rgba(0,0,0,.12)}.volume-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.volume-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.volume-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}@media (hover:none){.volume-theme .mat-expansion-panel:not(.mat-expanded):not([aria-disabled=true]) .mat-expansion-panel-header:hover{background:#fff}}.volume-theme .mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.volume-theme .mat-expansion-indicator::after,.volume-theme .mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.volume-theme .mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.26)}.volume-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.volume-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.volume-theme .mat-form-field-label,.volume-theme .mat-hint{color:rgba(0,0,0,.6)}.volume-theme .mat-form-field.mat-focused .mat-form-field-label{color:#76ff03}.volume-theme .mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:#ffc107}.volume-theme .mat-form-field.mat-focused .mat-form-field-label.mat-warn{color:#f44336}.volume-theme .mat-focused .mat-form-field-required-marker{color:#ffc107}.volume-theme .mat-form-field-ripple{background-color:rgba(0,0,0,.87)}.volume-theme .mat-form-field.mat-focused .mat-form-field-ripple{background-color:#76ff03}.volume-theme .mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:#ffc107}.volume-theme .mat-form-field.mat-focused .mat-form-field-ripple.mat-warn{background-color:#f44336}.volume-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid) .mat-form-field-infix::after{color:#76ff03}.volume-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:#ffc107}.volume-theme .mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-warn .mat-form-field-infix::after,.volume-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label,.volume-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.volume-theme .mat-form-field.mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.volume-theme .mat-form-field.mat-form-field-invalid .mat-form-field-ripple,.volume-theme .mat-form-field.mat-form-field-invalid .mat-form-field-ripple.mat-accent{background-color:#f44336}.volume-theme .mat-error{color:#f44336}.volume-theme .mat-form-field-appearance-legacy .mat-form-field-label,.volume-theme .mat-form-field-appearance-legacy .mat-hint{color:rgba(0,0,0,.54)}.volume-theme .mat-form-field-appearance-legacy .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.volume-theme .mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.volume-theme .mat-form-field-appearance-standard .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.volume-theme .mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x}.volume-theme .mat-form-field-appearance-fill .mat-form-field-flex{background-color:rgba(0,0,0,.04)}.volume-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-flex{background-color:rgba(0,0,0,.02)}.volume-theme .mat-form-field-appearance-fill .mat-form-field-underline::before{background-color:rgba(0,0,0,.42)}.volume-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.volume-theme .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-underline::before{background-color:transparent}.volume-theme .mat-form-field-appearance-outline .mat-form-field-outline{color:rgba(0,0,0,.12)}.volume-theme .mat-form-field-appearance-outline .mat-form-field-outline-thick{color:rgba(0,0,0,.87)}.volume-theme .mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick{color:#76ff03}.volume-theme .mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:#ffc107}.volume-theme .mat-form-field-appearance-outline.mat-focused.mat-warn .mat-form-field-outline-thick,.volume-theme .mat-form-field-appearance-outline.mat-form-field-invalid.mat-form-field-invalid .mat-form-field-outline-thick{color:#f44336}.volume-theme .mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,.38)}.volume-theme .mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{color:rgba(0,0,0,.06)}.volume-theme .mat-icon.mat-primary{color:#76ff03}.volume-theme .mat-icon.mat-accent{color:#ffc107}.volume-theme .mat-icon.mat-warn{color:#f44336}.volume-theme .mat-form-field-type-mat-native-select .mat-form-field-infix::after{color:rgba(0,0,0,.54)}.volume-theme .mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after,.volume-theme .mat-input-element:disabled{color:rgba(0,0,0,.38)}.volume-theme .mat-input-element{caret-color:#76ff03}.volume-theme .mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-input-element::placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-accent .mat-input-element{caret-color:#ffc107}.volume-theme .mat-form-field-invalid .mat-input-element,.volume-theme .mat-warn .mat-input-element{caret-color:#f44336}.volume-theme .mat-form-field-type-mat-native-select.mat-form-field-invalid .mat-form-field-infix::after{color:#f44336}.volume-theme .mat-list-base .mat-list-item,.volume-theme .mat-list-base .mat-list-option{color:rgba(0,0,0,.87)}.volume-theme .mat-list-base .mat-subheader{color:rgba(0,0,0,.54)}.volume-theme .mat-list-item-disabled{background-color:#eee}.volume-theme .mat-action-list .mat-list-item:focus,.volume-theme .mat-action-list .mat-list-item:hover,.volume-theme .mat-list-option:focus,.volume-theme .mat-list-option:hover,.volume-theme .mat-nav-list .mat-list-item:focus,.volume-theme .mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.volume-theme .mat-menu-panel{background:#fff}.volume-theme .mat-menu-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.volume-theme .mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.volume-theme .mat-menu-item[disabled],.volume-theme .mat-menu-item[disabled]::after{color:rgba(0,0,0,.38)}.volume-theme .mat-menu-item .mat-icon-no-color,.volume-theme .mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.volume-theme .mat-menu-item-highlighted:not([disabled]),.volume-theme .mat-menu-item.cdk-keyboard-focused:not([disabled]),.volume-theme .mat-menu-item.cdk-program-focused:not([disabled]),.volume-theme .mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.volume-theme .mat-paginator{background:#fff}.volume-theme .mat-paginator,.volume-theme .mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.volume-theme .mat-paginator-decrement,.volume-theme .mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.volume-theme .mat-paginator-first,.volume-theme .mat-paginator-last{border-top:2px solid rgba(0,0,0,.54)}.volume-theme .mat-icon-button[disabled] .mat-paginator-decrement,.volume-theme .mat-icon-button[disabled] .mat-paginator-first,.volume-theme .mat-icon-button[disabled] .mat-paginator-increment,.volume-theme .mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,.38)}.volume-theme .mat-progress-bar-background{fill:#dcedc8}.volume-theme .mat-progress-bar-buffer{background-color:#dcedc8}.volume-theme .mat-progress-bar-fill::after{background-color:#76ff03}.volume-theme .mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#ffecb3}.volume-theme .mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#ffecb3}.volume-theme .mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ffc107}.volume-theme .mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#ffcdd2}.volume-theme .mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.volume-theme .mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.volume-theme .mat-progress-spinner circle,.volume-theme .mat-spinner circle{stroke:#76ff03}.volume-theme .mat-progress-spinner.mat-accent circle,.volume-theme .mat-spinner.mat-accent circle{stroke:#ffc107}.volume-theme .mat-progress-spinner.mat-warn circle,.volume-theme .mat-spinner.mat-warn circle{stroke:#f44336}.volume-theme .mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.volume-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#76ff03}.volume-theme .mat-radio-button.mat-primary .mat-radio-inner-circle,.volume-theme .mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.volume-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple,.volume-theme .mat-radio-button.mat-primary:active .mat-radio-persistent-ripple{background-color:#76ff03}.volume-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ffc107}.volume-theme .mat-radio-button.mat-accent .mat-radio-inner-circle,.volume-theme .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.volume-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.volume-theme .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:#ffc107}.volume-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.volume-theme .mat-radio-button.mat-warn .mat-radio-inner-circle,.volume-theme .mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.volume-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-persistent-ripple,.volume-theme .mat-radio-button.mat-warn:active .mat-radio-persistent-ripple{background-color:#f44336}.volume-theme .mat-radio-button.mat-radio-disabled .mat-radio-outer-circle,.volume-theme .mat-radio-button.mat-radio-disabled.mat-radio-checked .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.volume-theme .mat-radio-button.mat-radio-disabled .mat-radio-inner-circle,.volume-theme .mat-radio-button.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.volume-theme .mat-radio-button.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.volume-theme .mat-radio-button .mat-ripple-element{background-color:#000}.volume-theme .mat-select-value{color:rgba(0,0,0,.87)}.volume-theme .mat-select-placeholder{color:rgba(0,0,0,.42)}.volume-theme .mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.volume-theme .mat-select-arrow{color:rgba(0,0,0,.54)}.volume-theme .mat-select-panel{background:#fff}.volume-theme .mat-select-panel:not([class*=mat-elevation-z]){box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.volume-theme .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.volume-theme .mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#76ff03}.volume-theme .mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ffc107}.volume-theme .mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.volume-theme .mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.volume-theme .mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.volume-theme .mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.volume-theme .mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.volume-theme .mat-drawer.mat-drawer-push{background-color:#fff}.volume-theme .mat-drawer:not(.mat-drawer-side){box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.volume-theme .mat-drawer-side{border-right:1px solid rgba(0,0,0,.12)}.volume-theme .mat-drawer-side.mat-drawer-end,.volume-theme [dir=rtl] .mat-drawer-side{border-left:1px solid rgba(0,0,0,.12);border-right:none}.volume-theme [dir=rtl] .mat-drawer-side.mat-drawer-end{border-left:none;border-right:1px solid rgba(0,0,0,.12)}.volume-theme .mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.volume-theme .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:#ffc107}.volume-theme .mat-slide-toggle.mat-checked .mat-slide-toggle-bar{background-color:rgba(255,193,7,.54)}.volume-theme .mat-slide-toggle.mat-checked .mat-ripple-element{background-color:#ffc107}.volume-theme .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb{background-color:#76ff03}.volume-theme .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar{background-color:rgba(118,255,3,.54)}.volume-theme .mat-slide-toggle.mat-primary.mat-checked .mat-ripple-element{background-color:#76ff03}.volume-theme .mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-thumb{background-color:#f44336}.volume-theme .mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-bar{background-color:rgba(244,67,54,.54)}.volume-theme .mat-slide-toggle.mat-warn.mat-checked .mat-ripple-element{background-color:#f44336}.volume-theme .mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:#000}.volume-theme .mat-slide-toggle-thumb{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);background-color:#fafafa}.volume-theme .mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.volume-theme .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.volume-theme .mat-primary .mat-slider-thumb,.volume-theme .mat-primary .mat-slider-thumb-label,.volume-theme .mat-primary .mat-slider-track-fill{background-color:#76ff03}.volume-theme .mat-primary .mat-slider-thumb-label-text{color:rgba(0,0,0,.87)}.volume-theme .mat-accent .mat-slider-thumb,.volume-theme .mat-accent .mat-slider-thumb-label,.volume-theme .mat-accent .mat-slider-track-fill{background-color:#ffc107}.volume-theme .mat-accent .mat-slider-thumb-label-text{color:rgba(0,0,0,.87)}.volume-theme .mat-warn .mat-slider-thumb,.volume-theme .mat-warn .mat-slider-thumb-label,.volume-theme .mat-warn .mat-slider-track-fill{background-color:#f44336}.volume-theme .mat-warn .mat-slider-thumb-label-text{color:#fff}.volume-theme .mat-slider-focus-ring{background-color:rgba(255,193,7,.2)}.volume-theme .cdk-focused .mat-slider-track-background,.volume-theme .mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.volume-theme .mat-slider-disabled .mat-slider-thumb,.volume-theme .mat-slider-disabled .mat-slider-track-background,.volume-theme .mat-slider-disabled .mat-slider-track-fill,.volume-theme .mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.volume-theme .mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.volume-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.volume-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.volume-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.volume-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.volume-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.volume-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.volume-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.volume-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.volume-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.volume-theme .mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.volume-theme .mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.volume-theme .mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.volume-theme .mat-step-header.cdk-keyboard-focused,.volume-theme .mat-step-header.cdk-program-focused,.volume-theme .mat-step-header:hover{background-color:rgba(0,0,0,.04)}@media (hover:none){.volume-theme .mat-step-header:hover{background:0 0}}.volume-theme .mat-step-header .mat-step-label,.volume-theme .mat-step-header .mat-step-optional{color:rgba(0,0,0,.54)}.volume-theme .mat-step-header .mat-step-icon{background-color:rgba(0,0,0,.54);color:rgba(0,0,0,.87)}.volume-theme .mat-step-header .mat-step-icon-selected,.volume-theme .mat-step-header .mat-step-icon-state-done,.volume-theme .mat-step-header .mat-step-icon-state-edit{background-color:#76ff03;color:rgba(0,0,0,.87)}.volume-theme .mat-step-header .mat-step-icon-state-error{background-color:transparent;color:#f44336}.volume-theme .mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.volume-theme .mat-step-header .mat-step-label.mat-step-label-error{color:#f44336}.volume-theme .mat-stepper-horizontal,.volume-theme .mat-stepper-vertical{background-color:#fff}.volume-theme .mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.volume-theme .mat-horizontal-stepper-header::after,.volume-theme .mat-horizontal-stepper-header::before,.volume-theme .mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.volume-theme .mat-sort-header-arrow{color:#757575}.volume-theme .mat-tab-header,.volume-theme .mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.volume-theme .mat-tab-group-inverted-header .mat-tab-header,.volume-theme .mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.volume-theme .mat-tab-label,.volume-theme .mat-tab-link{color:rgba(0,0,0,.87)}.volume-theme .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.volume-theme .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.volume-theme .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.volume-theme .mat-tab-group[class*=mat-background-] .mat-tab-header,.volume-theme .mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.volume-theme .mat-tab-group.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(220,237,200,.3)}.volume-theme .mat-tab-group.mat-primary .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#76ff03}.volume-theme .mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,236,179,.3)}.volume-theme .mat-tab-group.mat-accent .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#ffc107}.volume-theme .mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.volume-theme .mat-tab-group.mat-warn .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.volume-theme .mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.volume-theme .mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(220,237,200,.3)}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-header,.volume-theme .mat-tab-group.mat-background-primary .mat-tab-links,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#76ff03}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-label,.volume-theme .mat-tab-group.mat-background-primary .mat-tab-link,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.4)}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.4)}.volume-theme .mat-tab-group.mat-background-primary .mat-ripple-element,.volume-theme .mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(0,0,0,.12)}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,236,179,.3)}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-header,.volume-theme .mat-tab-group.mat-background-accent .mat-tab-links,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ffc107}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-label,.volume-theme .mat-tab-group.mat-background-accent .mat-tab-link,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.4)}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.volume-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.4)}.volume-theme .mat-tab-group.mat-background-accent .mat-ripple-element,.volume-theme .mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(0,0,0,.12)}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-group.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(255,205,210,.3)}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-header,.volume-theme .mat-tab-group.mat-background-warn .mat-tab-links,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-label,.volume-theme .mat-tab-group.mat-background-warn .mat-tab-link,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.volume-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.volume-theme .mat-tab-group.mat-background-warn .mat-ripple-element,.volume-theme .mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.volume-theme .mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.volume-theme .mat-toolbar.mat-primary{background:#76ff03;color:rgba(0,0,0,.87)}.volume-theme .mat-toolbar.mat-accent{background:#ffc107;color:rgba(0,0,0,.87)}.volume-theme .mat-toolbar.mat-warn{background:#f44336;color:#fff}.volume-theme .mat-toolbar .mat-focused .mat-form-field-ripple,.volume-theme .mat-toolbar .mat-form-field-ripple,.volume-theme .mat-toolbar .mat-form-field-underline{background-color:currentColor}.volume-theme .mat-toolbar .mat-focused .mat-form-field-label,.volume-theme .mat-toolbar .mat-form-field-label,.volume-theme .mat-toolbar .mat-form-field.mat-focused .mat-select-arrow,.volume-theme .mat-toolbar .mat-select-arrow,.volume-theme .mat-toolbar .mat-select-value{color:inherit}.volume-theme .mat-toolbar .mat-input-element{caret-color:currentColor}.volume-theme .mat-tooltip{background:rgba(97,97,97,.9)}.volume-theme .mat-tree{background:#fff}.volume-theme .mat-nested-tree-node,.volume-theme .mat-tree-node{color:rgba(0,0,0,.87)}.volume-theme .mat-snack-bar-container{color:rgba(255,255,255,.7);background:#323232;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.volume-theme .mat-simple-snackbar-action{color:#ffc107} \ No newline at end of file diff --git a/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.js b/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.js deleted file mode 100644 index a7779698f..000000000 --- a/openvidu-webcomponent/web/openvidu-webcomponent-2.10.0.js +++ /dev/null @@ -1,4 +0,0 @@ -!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c",this._properties=t&&t.properties||{},this._zoneDelegate=new u(this,this._parent&&this._parent._zoneDelegate,t)}return t.assertZonePatched=function(){if(e.Promise!==x.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(t,"root",{get:function(){for(var e=t.current;e.parent;)e=e.parent;return e},enumerable:!0,configurable:!0}),Object.defineProperty(t,"current",{get:function(){return j.zone},enumerable:!0,configurable:!0}),Object.defineProperty(t,"currentTask",{get:function(){return D},enumerable:!0,configurable:!0}),t.__load_patch=function(i,a){if(x.hasOwnProperty(i)){if(o)throw Error("Already loaded patch: "+i)}else if(!e["__Zone_disable_"+i]){var c="Zone:"+i;n(c),x[i]=a(e,t,P),r(c,c)}},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),t.prototype.get=function(e){var t=this.getZoneWith(e);if(t)return t._properties[e]},t.prototype.getZoneWith=function(e){for(var t=this;t;){if(t._properties.hasOwnProperty(e))return t;t=t._parent}return null},t.prototype.fork=function(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)},t.prototype.wrap=function(e,t){if("function"!=typeof e)throw new Error("Expecting function got: "+e);var n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}},t.prototype.run=function(e,t,n,r){j={parent:j,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{j=j.parent}},t.prototype.runGuarded=function(e,t,n,r){void 0===t&&(t=null),j={parent:j,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(o){if(this._zoneDelegate.handleError(this,o))throw o}}finally{j=j.parent}},t.prototype.runTask=function(e,t,n){if(e.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(e.zone||g).name+"; Execution: "+this.name+")");if(e.state!==_||e.type!==S&&e.type!==O){var r=e.state!=k;r&&e._transitionTo(k,b),e.runCount++;var o=D;D=e,j={parent:j,zone:this};try{e.type==O&&e.data&&!e.data.isPeriodic&&(e.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,e,t,n)}catch(i){if(this._zoneDelegate.handleError(this,i))throw i}}finally{e.state!==_&&e.state!==T&&(e.type==S||e.data&&e.data.isPeriodic?r&&e._transitionTo(b,k):(e.runCount=0,this._updateTaskCount(e,-1),r&&e._transitionTo(_,k,_))),j=j.parent,D=o}}},t.prototype.scheduleTask=function(e){if(e.zone&&e.zone!==this)for(var t=this;t;){if(t===e.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+e.zone.name);t=t.parent}e._transitionTo(m,_);var n=[];e._zoneDelegates=n,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(r){throw e._transitionTo(T,m,_),this._zoneDelegate.handleError(this,r),r}return e._zoneDelegates===n&&this._updateTaskCount(e,1),e.state==m&&e._transitionTo(b,m),e},t.prototype.scheduleMicroTask=function(e,t,n,r){return this.scheduleTask(new s(E,e,t,n,r,void 0))},t.prototype.scheduleMacroTask=function(e,t,n,r,o){return this.scheduleTask(new s(O,e,t,n,r,o))},t.prototype.scheduleEventTask=function(e,t,n,r,o){return this.scheduleTask(new s(S,e,t,n,r,o))},t.prototype.cancelTask=function(e){if(e.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(e.zone||g).name+"; Execution: "+this.name+")");e._transitionTo(w,b,k);try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo(T,w),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo(_,w),e.runCount=0,e},t.prototype._updateTaskCount=function(e,t){var n=e._zoneDelegates;-1==t&&(e._zoneDelegates=null);for(var r=0;r0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e})},e}(),s=function(){function t(n,r,o,i,a,c){this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=n,this.source=r,this.data=i,this.scheduleFn=a,this.cancelFn=c,this.callback=o;var u=this;this.invoke=n===S&&i&&i.useG?t.invokeTask:function(){return t.invokeTask.call(e,u,this,arguments)}}return t.invokeTask=function(e,t,n){e||(e=this),Z++;try{return e.runCount++,e.zone.runTask(e,t,n)}finally{1==Z&&y(),Z--}},Object.defineProperty(t.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),t.prototype.cancelScheduleRequest=function(){this._transitionTo(_,m)},t.prototype._transitionTo=function(e,t,n){if(this._state!==t&&this._state!==n)throw new Error(this.type+" '"+this.source+"': can not transition to '"+e+"', expecting state '"+t+"'"+(n?" or '"+n+"'":"")+", was '"+this._state+"'.");this._state=e,e==_&&(this._zoneDelegates=null)},t.prototype.toString=function(){return this.data&&void 0!==this.data.handleId?this.data.handleId.toString():Object.prototype.toString.call(this)},t.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}},t}(),l=C("setTimeout"),f=C("Promise"),p=C("then"),h=[],v=!1;function d(t){if(0===Z&&0===h.length)if(i||e[f]&&(i=e[f].resolve(0)),i){var n=i[p];n||(n=i.then),n.call(i,y)}else e[l](y,0);t&&h.push(t)}function y(){if(!v){for(v=!0;h.length;){var e=h;h=[];for(var t=0;t=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}};Zone.__load_patch("ZoneAwarePromise",function(t,n,r){var o=Object.getOwnPropertyDescriptor,i=Object.defineProperty,a=r.symbol,c=[],u=a("Promise"),s=a("then"),l="__creationTrace__";r.onUnhandledError=function(e){if(r.showUncaughtError()){var t=e&&e.rejection;t?console.error("Unhandled Promise rejection:",t instanceof Error?t.message:t,"; Zone:",e.zone.name,"; Task:",e.task&&e.task.source,"; Value:",t,t instanceof Error?t.stack:void 0):console.error(e)}},r.microtaskDrainDone=function(){for(;c.length;)for(var e=function(){var e=c.shift();try{e.zone.runGuarded(function(){throw e})}catch(t){p(t)}};c.length;)e()};var f=a("unhandledPromiseRejectionHandler");function p(e){r.onUnhandledError(e);try{var t=n[f];t&&"function"==typeof t&&t.call(this,e)}catch(o){}}function h(e){return e&&e.then}function v(e){return e}function d(e){return M.reject(e)}var y=a("state"),g=a("value"),_=a("finally"),m=a("parentPromiseValue"),b=a("parentPromiseState"),k="Promise.then",w=null,T=!0,E=!1,O=0;function S(e,t){return function(n){try{D(e,t,n)}catch(r){D(e,!1,r)}}}var x=function(){var e=!1;return function(t){return function(){e||(e=!0,t.apply(null,arguments))}}},P="Promise resolved with itself",j=a("currentTaskTrace");function D(e,t,o){var a,u=x();if(e===o)throw new TypeError(P);if(e[y]===w){var s=null;try{"object"!=typeof o&&"function"!=typeof o||(s=o&&o.then)}catch(d){return u(function(){D(e,!1,d)})(),e}if(t!==E&&o instanceof M&&o.hasOwnProperty(y)&&o.hasOwnProperty(g)&&o[y]!==w)z(o),D(e,o[y],o[g]);else if(t!==E&&"function"==typeof s)try{s.call(o,u(S(e,t)),u(S(e,!1)))}catch(d){u(function(){D(e,!1,d)})()}else{e[y]=t;var f=e[g];if(e[g]=o,e[_]===_&&t===T&&(e[y]=e[b],e[g]=e[m]),t===E&&o instanceof Error){var p=n.currentTask&&n.currentTask.data&&n.currentTask.data[l];p&&i(o,j,{configurable:!0,enumerable:!1,writable:!0,value:p})}for(var h=0;h=0;n--)"function"==typeof e[n]&&(e[n]=h(e[n],t+"_"+n));return e}function w(e){return!e||!1!==e.writable&&!("function"==typeof e.get&&void 0===e.set)}var T="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,E=!("nw"in _)&&void 0!==_.process&&"[object process]"==={}.toString.call(_.process),O=!E&&!T&&!(!y||!g.HTMLElement),S=void 0!==_.process&&"[object process]"==={}.toString.call(_.process)&&!T&&!(!y||!g.HTMLElement),x={},P=function(e){if(e=e||_.event){var t=x[e.type];t||(t=x[e.type]=d("ON_PROPERTY"+e.type));var n,r=this||e.target||_,o=r[t];return O&&r===g&&"error"===e.type?!0===(n=o&&o.call(this,e.message,e.filename,e.lineno,e.colno,e.error))&&e.preventDefault():null==(n=o&&o.apply(this,arguments))||n||e.preventDefault(),n}};function j(e,r,o){var i=t(e,r);if(!i&&o&&t(o,r)&&(i={enumerable:!0,configurable:!0}),i&&i.configurable){var a=d("on"+r+"patched");if(!e.hasOwnProperty(a)||!e[a]){delete i.writable,delete i.value;var c=i.get,u=i.set,s=r.substr(2),l=x[s];l||(l=x[s]=d("ON_PROPERTY"+s)),i.set=function(t){var n=this;n||e!==_||(n=_),n&&(n[l]&&n.removeEventListener(s,P),u&&u.apply(n,b),"function"==typeof t?(n[l]=t,n.addEventListener(s,P,!1)):n[l]=null)},i.get=function(){var t=this;if(t||e!==_||(t=_),!t)return null;var n=t[l];if(n)return n;if(c){var o=c&&c.call(this);if(o)return i.set.call(this,o),"function"==typeof t[m]&&t.removeAttribute(r),o}return null},n(e,r,i),e[a]=!0}}}function D(e,t,n){if(t)for(var r=0;r=0&&"function"==typeof r[i.cbIdx]?v(i.name,r[i.cbIdx],i,o):e.apply(t,r)}})}function I(e,t){e[d("OriginalDelegate")]=t}var F=!1,L=!1;function A(){try{var e=g.navigator.userAgent;if(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/"))return!0}catch(t){}return!1}function N(){if(F)return L;F=!0;try{var e=g.navigator.userAgent;-1===e.indexOf("MSIE ")&&-1===e.indexOf("Trident/")&&-1===e.indexOf("Edge/")||(L=!0)}catch(t){}return L}Zone.__load_patch("toString",function(e){var t=Function.prototype.toString,n=d("OriginalDelegate"),r=d("Promise"),o=d("Error"),i=function(){if("function"==typeof this){var i=this[n];if(i)return"function"==typeof i?t.call(i):Object.prototype.toString.call(i);if(this===Promise){var a=e[r];if(a)return t.call(a)}if(this===Error){var c=e[o];if(c)return t.call(c)}}return t.call(this)};i[n]=t,Function.prototype.toString=i;var a=Object.prototype.toString;Object.prototype.toString=function(){return this instanceof Promise?"[object Promise]":a.call(this)}});var q=!1;if("undefined"!=typeof window)try{var H=Object.defineProperty({},"passive",{get:function(){q=!0}});window.addEventListener("test",H,H),window.removeEventListener("test",H,H)}catch(Te){q=!1}var W={useG:!0},U={},X={},G=/^__zone_symbol__(\w+)(true|false)$/,B="__zone_symbol__propagationStopped";function K(e,t,n){var o=n&&n.add||a,i=n&&n.rm||c,u=n&&n.listeners||"eventListeners",s=n&&n.rmAll||"removeAllListeners",h=d(o),v="."+o+":",y="prependListener",g="."+y+":",_=function(e,t,n){if(!e.isRemoved){var r=e.callback;"object"==typeof r&&r.handleEvent&&(e.callback=function(e){return r.handleEvent(e)},e.originalDelegate=r),e.invoke(e,t,[n]);var o=e.options;o&&"object"==typeof o&&o.once&&t[i].call(t,n.type,e.originalDelegate?e.originalDelegate:e.callback,o)}},m=function(t){if(t=t||e.event){var n=this||t.target||e,r=n[U[t.type][f]];if(r)if(1===r.length)_(r[0],n,t);else for(var o=r.slice(),i=0;i1?new i(t,n):new i(t),s=e.ObjectGetOwnPropertyDescriptor(u,"onmessage");return s&&!1===s.configurable?(a=e.ObjectCreate(u),c=u,[r,o,"send","close"].forEach(function(t){a[t]=function(){var n=e.ArraySlice.call(arguments);if(t===r||t===o){var i=n.length>0?n[0]:void 0;if(i){var c=Zone.__symbol__("ON_PROPERTY"+i);u[c]=a[c]}}return u[t].apply(u,n)}})):a=u,e.patchOnProperties(a,["close","error","message","open"],c),a};var a=t.WebSocket;for(var c in i)a[c]=i[c]}(e,t),Zone[e.symbol("patchEvents")]=!0)}}Zone.__load_patch("util",function(e,r,u){u.patchOnProperties=D,u.patchMethod=M,u.bindArguments=k,u.patchMacroTask=R;var s=r.__symbol__("BLACK_LISTED_EVENTS"),v=r.__symbol__("UNPATCHED_EVENTS");e[v]&&(e[s]=e[v]),e[s]&&(r[s]=r[v]=e[s]),u.patchEventPrototype=V,u.patchEventTarget=K,u.isIEOrEdge=N,u.ObjectDefineProperty=n,u.ObjectGetOwnPropertyDescriptor=t,u.ObjectCreate=o,u.ArraySlice=i,u.patchClass=z,u.wrapWithCurrentZone=h,u.filterProperties=ge,u.attachOriginToPatched=I,u._redefineProperty=re,u.patchCallbacks=J,u.getGlobalObjects=function(){return{globalSources:X,zoneSymbolEventNames:U,eventNames:ye,isBrowser:O,isMix:S,isNode:E,TRUE_STR:l,FALSE_STR:f,ZONE_SYMBOL_PREFIX:p,ADD_EVENT_LISTENER_STR:a,REMOVE_EVENT_LISTENER_STR:c}}}),function(e){e.__zone_symbol__legacyPatch=function(){var t=e.Zone;t.__load_patch("registerElement",function(e,t,n){!function(e,t){var n=t.getGlobalObjects();(n.isBrowser||n.isMix)&&"registerElement"in e.document&&t.patchCallbacks(t,document,"Document","registerElement",["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"])}(e,n)}),t.__load_patch("EventTargetLegacy",function(e,t,n){!function(e,t){var n=t.getGlobalObjects(),r=n.eventNames,o=n.globalSources,i=n.zoneSymbolEventNames,a=n.TRUE_STR,c=n.FALSE_STR,u=n.ZONE_SYMBOL_PREFIX,s="Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video",l="ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex,WebSocket".split(","),f=[],p=e.wtf,h=s.split(",");p?f=h.map(function(e){return"HTML"+e+"Element"}).concat(l):e.EventTarget||(f=l);for(var v=e.__Zone_disable_IE_check||!1,d=e.__Zone_enable_cross_context_check||!1,y=t.isIEOrEdge(),g="function __BROWSERTOOLS_CONSOLE_SAFEFUNC() { [native code] }",_=0;_0){var o=e.invoke;e.invoke=function(){for(var n=r.__zone_symbol__loadfalse,i=0;i0?arguments[0]:void 0)}},{get:function(e){var t=r.getEntry(o(this,"Map"),e);return t&&t.v},set:function(e,t){return r.def(o(this,"Map"),0===e?0:e,t)}},r,!0)},"9gX7":function(e,t){e.exports=function(e,t,n,r){if(!(e instanceof t)||void 0!==r&&r in e)throw TypeError(n+": incorrect invocation!");return e}},Afnz:function(e,t,n){"use strict";var r=n("LQAc"),o=n("XKFU"),i=n("KroJ"),a=n("Mukb"),c=n("hPIQ"),u=n("QaDb"),s=n("fyDq"),l=n("OP3Y"),f=n("K0xU")("iterator"),p=!([].keys&&"next"in[].keys()),h=function(){return this};e.exports=function(e,t,n,v,d,y,g){u(n,t,v);var _,m,b,k=function(e){if(!p&&e in O)return O[e];switch(e){case"keys":case"values":return function(){return new n(this,e)}}return function(){return new n(this,e)}},w=t+" Iterator",T="values"==d,E=!1,O=e.prototype,S=O[f]||O["@@iterator"]||d&&O[d],x=S||k(d),P=d?T?k("entries"):x:void 0,j="Array"==t&&O.entries||S;if(j&&(b=l(j.call(new e)))!==Object.prototype&&b.next&&(s(b,w,!0),r||"function"==typeof b[f]||a(b,f,h)),T&&S&&"values"!==S.name&&(E=!0,x=function(){return S.call(this)}),r&&!g||!p&&!E&&O[f]||a(O,f,x),c[t]=x,c[w]=h,d)if(_={values:T?x:k("values"),keys:y?x:k("keys"),entries:P},g)for(m in _)m in O||i(O,m,_[m]);else o(o.P+o.F*(p||E),t,_);return _}},BqfV:function(e,t,n){var r=n("N6cJ"),o=n("y3w9"),i=r.get,a=r.key;r.exp({getOwnMetadata:function(e,t){return i(e,o(t),arguments.length<3?void 0:a(arguments[2]))}})},CkkT:function(e,t,n){var r=n("m0Pp"),o=n("Ymqv"),i=n("S/j/"),a=n("ne8i"),c=n("zRwo");e.exports=function(e,t){var n=1==e,u=2==e,s=3==e,l=4==e,f=6==e,p=5==e||f,h=t||c;return function(t,c,v){for(var d,y,g=i(t),_=o(g),m=r(c,v,3),b=a(_.length),k=0,w=n?h(t,b):u?h(t,0):void 0;b>k;k++)if((p||k in _)&&(y=m(d=_[k],k,g),e))if(n)w[k]=y;else if(y)switch(e){case 3:return!0;case 5:return d;case 6:return k;case 2:w.push(d)}else if(l)return!1;return f?-1:s||l?l:w}}},DVgA:function(e,t,n){var r=n("zhAb"),o=n("4R4u");e.exports=Object.keys||function(e){return r(e,o)}},EK0E:function(e,t,n){"use strict";var r,o=n("dyZX"),i=n("CkkT")(0),a=n("KroJ"),c=n("Z6vF"),u=n("czNK"),s=n("ZD67"),l=n("0/R4"),f=n("s5qY"),p=n("s5qY"),h=!o.ActiveXObject&&"ActiveXObject"in o,v=c.getWeak,d=Object.isExtensible,y=s.ufstore,g=function(e){return function(){return e(this,arguments.length>0?arguments[0]:void 0)}},_={get:function(e){if(l(e)){var t=v(e);return!0===t?y(f(this,"WeakMap")).get(e):t?t[this._i]:void 0}},set:function(e,t){return s.def(f(this,"WeakMap"),e,t)}},m=e.exports=n("4LiD")("WeakMap",g,_,s,!0,!0);p&&h&&(u((r=s.getConstructor(g,"WeakMap")).prototype,_),c.NEED=!0,i(["delete","has","get","set"],function(e){var t=m.prototype,n=t[e];a(t,e,function(t,o){if(l(t)&&!d(t)){this._f||(this._f=new r);var i=this._f[e](t,o);return"set"==e?this:i}return n.call(this,t,o)})}))},EWmC:function(e,t,n){var r=n("LZWt");e.exports=Array.isArray||function(e){return"Array"==r(e)}},EemH:function(e,t,n){var r=n("UqcF"),o=n("RjD/"),i=n("aCFj"),a=n("apmT"),c=n("aagx"),u=n("xpql"),s=Object.getOwnPropertyDescriptor;t.f=n("nh4g")?s:function(e,t){if(e=i(e),t=a(t,!0),u)try{return s(e,t)}catch(n){}if(c(e,t))return o(!r.f.call(e,t),e[t])}},FJW5:function(e,t,n){var r=n("hswa"),o=n("y3w9"),i=n("DVgA");e.exports=n("nh4g")?Object.defineProperties:function(e,t){o(e);for(var n,a=i(t),c=a.length,u=0;c>u;)r.f(e,n=a[u++],t[n]);return e}},FZcq:function(e,t,n){n("49D4"),n("zq+C"),n("45Tv"),n("uAtd"),n("BqfV"),n("fN/3"),n("iW+S"),n("7Dlh"),n("Opxb"),e.exports=n("g3g5").Reflect},H6hf:function(e,t,n){var r=n("y3w9");e.exports=function(e,t,n,o){try{return o?t(r(n)[0],n[1]):t(n)}catch(a){var i=e.return;throw void 0!==i&&r(i.call(e)),a}}},"I8a+":function(e,t,n){var r=n("LZWt"),o=n("K0xU")("toStringTag"),i="Arguments"==r(function(){return arguments}());e.exports=function(e){var t,n,a;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(n){}}(t=Object(e),o))?n:i?r(t):"Object"==(a=r(t))&&"function"==typeof t.callee?"Arguments":a}},Iw71:function(e,t,n){var r=n("0/R4"),o=n("dyZX").document,i=r(o)&&r(o.createElement);e.exports=function(e){return i?o.createElement(e):{}}},"J+6e":function(e,t,n){var r=n("I8a+"),o=n("K0xU")("iterator"),i=n("hPIQ");e.exports=n("g3g5").getIteratorMethod=function(e){if(null!=e)return e[o]||e["@@iterator"]||i[r(e)]}},JiEa:function(e,t){t.f=Object.getOwnPropertySymbols},K0xU:function(e,t,n){var r=n("VTer")("wks"),o=n("ylqs"),i=n("dyZX").Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},KroJ:function(e,t,n){var r=n("dyZX"),o=n("Mukb"),i=n("aagx"),a=n("ylqs")("src"),c=n("+lvF"),u=(""+c).split("toString");n("g3g5").inspectSource=function(e){return c.call(e)},(e.exports=function(e,t,n,c){var s="function"==typeof n;s&&(i(n,"name")||o(n,"name",t)),e[t]!==n&&(s&&(i(n,a)||o(n,a,e[t]?""+e[t]:u.join(String(t)))),e===r?e[t]=n:c?e[t]?e[t]=n:o(e,t,n):(delete e[t],o(e,t,n)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[a]||c.call(this)})},Kuth:function(e,t,n){var r=n("y3w9"),o=n("FJW5"),i=n("4R4u"),a=n("YTvA")("IE_PROTO"),c=function(){},u=function(){var e,t=n("Iw71")("iframe"),r=i.length;for(t.style.display="none",n("+rLv").appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("